【问题标题】:Tricky MySQL JOIN query棘手的 MySQL JOIN 查询
【发布时间】:2014-07-15 21:18:22
【问题描述】:

我有一个文本输入,在键入时我想更新相邻选择字段中的选项。

我的数据库中有这两个表:

型号:

ID  modelName  brandID
1   NA140           3
1   SRL             1
1   SRS             1
1   SRF             1
1   SMS             2
1   SMU             2

品牌:

ID  brandName
1    Samsung
2    Bosch
3    Panasonic

在选择字段中,我想列出品牌表中的所有brandNames,但列出与文本输入相关的它们。 因此,如果输入“SR”,modelNames 的顺序将是 SRF、SRL、SRS、SMU、SMS、NA140,然后作为结果抓取相应的brandName,但每个品牌只列出一次。

我将如何编写这个查询?

我有这个基本的想法,我认为这是我需要的......

JOIN models & brands ON m.brandID = b.ID

MATCH modelName to string%

SELECT UNIQUE brandName 

【问题讨论】:

  • 如果键入了 SR,NA140 是否仍应列为模型名称?为什么(因为 NA140 不含 SR)?
  • 查询的表格形式的期望结果是什么?
  • @Joeseph B - 用户将开始在文本输入中键入型号,并且在每次按键时它将使用 ajax 提取数据。此数据将使用我的品牌表中的所有品牌名称填充一个选择字段,但将对它们进行排序,以便顶部选项与正在输入的型号最匹配

标签: mysql sql join


【解决方案1】:

我能想到的唯一方法是首先在与用户输入匹配的位置进行选择,获取这些结果,然后在它匹配的位置再次执行,并将结果与​​联合合并,如下所示:

(SELECT `t1`.`modelName`, `t1`.`brandID`,`t2`.`brandName` FROM `Models` as `t1` INNER JOIN `Brands` AS `t2` ON `t1`.`brandID`=`t2`.`ID` WHERE `t1`.`modelName` LIKE 'SR%' ORDER BY `t1`.`modelName`,`t2`.`brandName`)
UNION
(SELECT `t1`.`modelName`, `t1`.`brandID`,`t2`.`brandName` FROM `Models` as `t1` INNER JOIN `Brands` AS `t2` ON `t1`.`brandID`=`t2`.`ID` WHERE `t1`.`modelName` NOT LIKE 'SR%' ORDER BY `t1`.`modelName`,`t2`.`brandName`)

可能有一种更有效的方法来做到这一点,这是我去商店之前能想到的:)

【讨论】:

  • 您可以只选择一般数据并在服务器端脚本中对结果集进行排序。
【解决方案2】:
select distinct brandName 
from Models m inner join Brands b
on m.brandID = b.ID
where m.modelName like 's%'

Fiddle

【讨论】:

  • 这仅显示与 LIKE 匹配的型号的品牌。我希望所有品牌都输出,但在输出的顶部有最佳匹配。
【解决方案3】:

我想出了一个类似的查询(简化):

select brandName from (
select b.brandName as brandName, m.modelName 
from brands b join models m 
on m.brandid = b.id 
where m.modelName like '%sr%'
union
select b.brandName as brandName, m.modelName 
from brands b join models m 
on m.brandid = b.id 
where m.modelName not like '%sr%') as curb
group by brandName

SQLfiddle:http://sqlfiddle.com/#!2/593b36/30

(品牌型号不准确)

【讨论】:

  • 这更像是我需要的。但我需要 'SELECT DISTINCT b.brandName' 没有 modelName 输出
  • 虽然我认为你们都想要modelNames,但我改进了我的答案
  • 这个版本更改LIKE字符串没有任何影响
【解决方案4】:
SELECT DISTINCT b.brandName 
FROM brands b 
JOIN models m 
ON m.brandID = b.id 
WHERE m.modelName LIKE '%$variable%' 

UNION 
SELECT b.brandName 
FROM brands b 
JOIN models m 
ON m.brandID = b.id 
WHERE m.modelName NOT LIKE '%$variable%'

【讨论】:

    【解决方案5】:

    需要一个函数来计算字段、anchor中的值和table中的值之间的距离,这个函数可以是anchor的HEX和anchor的HEX之间的差值表值。

    SELECT m.id, modelName, brandName
    FROM   Model m
           INNER JOIN Brand b ON m.brandID = b.ID
    ORDER BY ABS(CONV(HEX(RPAD('SR', 5, ' ')), 16, 10) 
               - CONV(HEX(RPAD(modelName, 5, ' ')), 16, 10))
    

    SQLFiddle Demo

    在将值传递给HEX 之前,要获得正确的结果,需要对字符串进行填充,使它们都具有相同的长度,这就是为什么会有RPAD

    为了计算差异,将值从 base-16 转换为 base-10,因为距离仅使用正数 ABS

    如果有名称超过五个字符的模型,则RPAD的参数需要修改为最长模型的长度。

    【讨论】:

      【解决方案6】:

      你在寻找这样的东西吗?

      SELECT DISTINCT brandname
        FROM models m JOIN brands b
          ON m.brandid = b.id
       ORDER BY modelname LIKE 'S%' DESC,
                modelname LIKE 'SR%' DESC,
                modelname
      

      输出:

      |品牌名称 | |-----------| |三星 | |博世 | |松下 |

      这里是SQLFiddle演示

      更新:对于SMU% 输入字符串,查询应该看起来像

      SELECT DISTINCT brandname
        FROM models m JOIN brands b
          ON m.brandid = b.id
       ORDER BY modelname LIKE 'S%' DESC,
                modelname LIKE 'SM%' DESC,
                modelname LIKE 'SMU%' DESC,
                modelname
      

      输出:

      |品牌名称 | |-----------| |博世 | |三星 | |松下 |

      这里是SQLFiddle演示

      【讨论】:

      • 这就是我所追求的!我的字符串将根据用户输入是可变的,所以我只需要它就像 code SELECT DISTINCT brandname FROM models m JOIN brands b ON m.brandid = b.id ORDER BY modelname LIKE 'S%' DESC, modelname 和 'S%' 将是 'variable%' 我用几个不同的字符串对此进行了测试,除了使用 'SMU 时一切正常%' 输出有 'Panasonic 在顶部应该是 'Bosch' 你知道为什么会这样吗?
      • 看看更新。您必须根据输入字符串的长度动态构建ORDER BY 子句。鉴于您的样本数据,博世将始终位于顶部。
      • @user3773147 有帮助吗?
      • 我只需要一个字符串就可以了。这将是从每个键盘上的用户输入发送的变量。我已经发布了我正在使用的代码作为完美工作的答案。当我被允许时,我会标记为最佳答案。
      【解决方案7】:

      我认为解决方案不应该出现在查询部分......至少对于每个键入的字母。也许您可以对第一个字母进行一次查询,将该字母的数据检索到客户端部分,将名称放入数组中,然后在客户端进行排序。 在服务器端执行此操作显然较慢,但考虑到用户输入错误字母、删除(将进行新查询)和再次输入(新查询)的次数,对每个输入的字母进行查询,在性能方面。 将计算放在客户端要好得多。只有当第一个字母已被删除并键入一个新字母时,您才能重做查询。 可能您需要一些为什么每次都进行新查询,但是..也许不同的方法可以帮助找到更好的解决方案...

      【讨论】:

      • 我的数据库很小,现在效率不是问题。一旦我完成了我的网站,我可能会回到这里并以这种方式重新工作 =)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      相关资源
      最近更新 更多