简体   繁体   English

具有多个子选择的MySQL SQL选择查询

[英]MySQL SQL Select Query with Multiple Sub-Selects

OK, so this one has had me ripping my hair out for hours. 好,所以这个让我扯了几个小时。 I feel like there is something obvious I am overlooking. 我觉得有些明显的事情我正在忽略。

I have 2 tables, service and brand 我有2张桌子, 服务品牌

service
-------
id
brand

brand
-----
id
brandName

So service.brand can be any of these: 因此,service.brand可以是以下任意一种:

Blank 
"Other" 
Integer (matches brand.id) 
String (matches brand.brandName)
String (Not Blank, Not Other, Not brand.brandName)

I'm trying to write a query that will pull up the correct brandname from the brand table, and if the value of service.brand is not in brand.id or brand.brandName, then display whatever is there. 我正在尝试编写一个查询,该查询将从brand表中拉出正确的brandname,如果service.brand的值不在brand.id或brand.brandName中,则显示其中的内容。

So far I got everything working except it wouldn't pull up the record if service.brand was Not Blank, Not Other, Not in brand.id, Not in brand.brandName. 到目前为止,我已经做好了所有工作,但是如果service.brand不为空,不是Other,不在brand.id中,不在brand.brandName中,则不会提高记录。 (which I'm calling OtherThanOther from here on out). (从现在开始,我将其称为OtherThanOther)。

Now my latest attempt pulls up mostly correct, but the OtherThanOther field gets pulled up many times, like if total records is 40, OtherThanOther is the same record almost 20 times. 现在,我的最新尝试几乎是正确的,但是OtherThanOther字段却被拉很多次,例如总记录为40,OtherThanOther几乎是同一记录的20倍。 HELP! 救命!

My latest attempt.. 我最近的尝试

select 
    s.*, b.brandName as bname 
from 
    service s, brand b 
where 
    s.brand = b.brandName 
or 
    s.brand = b.id 
or 
    s.brand = 'Other' 
or 
    s.brand = ''
or
    (       
        s.brand not in (select brandName from brand)
        and
        s.brand not in (select id from brand)
        and
        s.brand != 'Other'
        and
        s.brand != ''
    )

Sample Table Data 样本表数据

service
-------
1 5
2 Dell
3 SomeRandom
4 
5 Other

brand
-----

1 HP
2 Gateway
3 Dell
4 Compaq
5 Toshiba

my query results.. 我的查询结果

(service.id, service.brand, brand.id, brand.brandName, bname)
-------------------------------------------------------------
1 5 5 Toshiba Toshiba
2 Dell 3 Dell Dell
3 SomeRandom, brand.id, brand.brandName, brand.brandName
3 SomeRandom, brand.id, brand.brandName, brand.brandName
3 SomeRandom, brand.id, brand.brandName, brand.brandName
3 SomeRandom, brand.id, brand.brandName, brand.brandName
3 SomeRandom, brand.id, brand.brandName, brand.brandName
4 '', null, null, null
5 Other, null, null, null

I need it to just pull SomeRandom once, group by won't work because there may be multiple fields with the same value as SomeRandom. 我需要它只拉一次SomeRandom,分组依据将无法工作,因为可能有多个字段的值与SomeRandom相同。 Any help is much appreciated. 任何帮助深表感谢。

Thanks! 谢谢!

select 
    s.*, 
    CASE 
      WHEN b_id.brandName IS NOT NULL THEN b_id.brandName
      WHEN b.brandName IS NOT NULL THEN b.brandName
      ELSE s.brand 
    END as bname 
from 
    service s
LEFT JOIN brand b_id 
ON  CAST(s.brand AS UNSIGNED) = b_id.id
LEFT JOIN brand b
ON  s.brand = b.brandName

You are using an old style inner join : 您正在使用旧式inner join

from service s, brand b 
where s.brand = b.brandName or ...

More clearly written like: 更清晰地写为:

from service s
inner join brand b on s.brand = b.brandName or ... 

In the newer form, the problem immediately stands out. 在较新的形式中,问题立即突出。 An inner join filters out unmatched rows. inner join过滤出不匹配的行。 Use a left join instead: 使用left join

from service s
left join brand b on s.brand = b.brandName or ...

Now you'll get all services, even if no matching row was found in the brand table. 现在,即使在brand表中未找到匹配的行,您也将获得所有服务。

You should JOIN 2 tables with multiple conditions. 您应该JOIN具有多个条件的2个表。 Something like this: 像这样:

SELECT s.*, b.brandName AS bname
FROM service AS s
INNER JOIN brand AS b
ON s.brand = b.brandName OR 
   s.brand = b.id OR 
   s.brand = 'Other' OR 
   s.brand = '' OR  
   (s.brand NOT IN (SELECT brandName FROM brand) AND
   s.brand NOT IN (SELECT id FROM brand) AND 
   s.brand != 'Other' AND
   s.brand != '') 

First thing - use JOIN! 第一件事-使用JOIN!

select s.*, b.brandName as bname 
from service s 
    LEFT JOIN brand b ON s.brand = b.brandName or s.brand = b.id

Then you can add your sensemaking conditions - for example WHERE NOT s.brand IS NULL 然后,您可以添加WHERE NOT s.brand IS NULL条件-例如WHERE NOT s.brand IS NULL

These condotions of you are leading to the result in which your table rows are multiplied with each other: 您的这些情况导致表行彼此相乘的结果:

s.brand = 'Other' 
or 
    s.brand = ''
or
     (       
        s.brand not in (select brandName from brand)
        and
        s.brand not in (select id from brand)
        and
        s.brand != 'Other'
        and
        s.brand != ''
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM