如果这些行中至少有一个具有给定值,则选择具有给定 ID 的所有行

Posted

技术标签:

【中文标题】如果这些行中至少有一个具有给定值,则选择具有给定 ID 的所有行【英文标题】:SELECT all rows with a given ID if at least one of those rows has a given value 【发布时间】:2012-05-10 18:18:40 【问题描述】:

我有一个 mysql 查询,它将选择一些饮料并返回有关该饮料的基本信息,以及该特定饮料的成分列表以及该特定饮料的评级。我有 3 桌酒水,drinks_ratings,drinks_ing

所以,我的问题是说我想获取有关包含伏特加的饮料的信息,并且在高球杯中,我将运行下面的查询...

它有效,只是我的问题是它不会返回所有成分。例如,如果我返回“randomDrinkName1”并且它恰好有伏特加和苏打水......当我得到信息时,它会忽略苏打水,因为我说 WHERE ing = voda,所以我明白为什么会发生这种情况。 ..但是我可以做一些其他类型的 WHERE 子句来检查它是否有“伏特加”并将其与所有其他可能存在的成分信息一起返回?

我知道我可以在这个查询之前做一个查询,从我的drinks_ing 表中获取包含伏特加的ID。

但这似乎是个坏主意……例如,如果有 1000 多种带有伏特加的饮料,只是为了对带有 1000 条 OR 语句的选择进行查询。

如果有一种方法可以让我在一个查询中轻松完成这一切,我很感兴趣。谢谢!

select dIngs.id,
    dIngs.name,
    dIngs.descrip,
    dIngs.type,
    dIngs.ing,
    AVG(b.rating) as arating,
    COUNT(b.id) as tvotes
from (
    select a.id,
        a.name,
        a.descrip,
        a.type,
        concat (
            '[',
            GROUP_CONCAT('\"ing\":', c.ing, ',\"parts\":', c.parts, ''),
            ']'
            ) ing
    from drinks a
    left join drinks_ing c on a.id = c.did
    where c.ing = "vodka"
        and a.type = "highball"
    group by a.id
    ) dIngs
left join drinks_ratings b on dIngs.id = b.id
group by dIngs.id
order by arating desc,
    tvotes desc LIMIT 0,
    50;

编辑: 为了说明我想要得到的结果是这样的:

           [0]
              descrip = "the description text will be here"
              arating = 0
              id = 4
              ing = [ "ing": "vodka", "parts": 4, "ing": "soda", "parts": 2, "ing": "sprite", "parts": 2 ]
              name = "awesomeDrink"
              type = "highball"
              tvotes = 0

但我实际上得到的只是伏特加,因为那是我正在检查的

           [0]
              descrip = "the description text will be here"
              arating = 0
              id = 4
              ing = [ "ing": "vodka", "parts": 4 ]
              name = "awesomeDrink"
              type = "highball"
              tvotes = 0

需要明确的是,如果我不提供 where ing = vodka 之类的东西,我可以把所有的原料都拿回来。这不是问题....

我需要它来检查其中一种潜在成分是否恰好是伏特加,然后基本上返回所有 ing 数据......如果伏特加不是潜在成分,则忽略该饮料并且不返回它。

编辑: 我的桌子是什么样子的..

drinks_ing
---------------
did (which is the drink id its associated with)
id (the id of the ingredient aka "vodka")
parts

drinks
---------------
id
name
description
type
timestamp

drinks_ratings
-----------------
id
userid
rating
timestamp

【问题讨论】:

请发布一些示例数据以供使用。 为什么...为什么要在 SQL 中构建 JSON 而不是在 php 中使用 json_encode() 构建 JSON? 你能发布你的 3 个表和一些示例数据的表创建语句吗? 【参考方案1】:

您最好的方法可能是使用自联接。这是您引用同一个表两次但名称不同的地方。大致如下:

SELECT     d.stuff
FROM       drinks d
INNER JOIN drinks v on d.id = v.id
WHERE      v.ingredient = "vodka"

更新:使其更好地对应于相关表格。这就是说:给定所有伏特加成分,找出与该伏特加成分相同的饮料中的所有成分。

SELECT     d.*
FROM       drinks_ing d
INNER JOIN drinks_ing v on d.did = v.did
WHERE      v.ing = "vodka"

【讨论】:

我不确定这是否与我获取评级的方式兼容,以及我需要如何将所有成分作为 JSON 字符串取回 我认为您应该首先担心收集感兴趣的数据,并且只有在您完成查询的该方面后,然后再担心将其格式化为 JSON。你应该对你的问题采取分而治之的方法;一次解决一件事。 是的,我正在简化您的表结构;我这样做是为了让您清楚自我加入的工作原理。您将需要调整此技术以使用更复杂的表结构。您是否了解什么是自我加入以及为什么它与您的问题相关? 我想我只是不明白你在说什么。我不是一个真正的 SQL 人。所以,我尝试了FROM drinks a INNER JOIN drinks_ing c ON a.id = c.did where c.ing=1(1 是伏特加),但我仍然只是把伏特加成分拿回来。 好吧,我想我明白你在说什么,因为它现在可以工作了!非常感谢!【参考方案2】:

是的,您可以在一个查询中完成。你的客栈

SELECT a.id, a.name, a.descrip, a.type, CONCAT('[', GROUP_CONCAT('\"ing\":', c.ing, ',\"parts\":', c.parts, ''), ']') ing
FROM drinks a LEFT JOIN drinks_ing c
     ON a.id = c.did
WHERE a.id in (select distinct a.id
                from drinks_ing c
                     ON a.id = c.did
                where c.ing = "vodka"
               )

这会找到您想要的成分的饮料并返回有关饮料的信息。

【讨论】:

更详细地解释一下:子查询获取所有以伏特加为成分的饮料的 ID,外部查询选择这些饮料的所有成分。 对不起,这个方法与我需要它做的所有事情都不兼容。例如获取所有成分,以及获取平均评级并将其与该特定行相关联。我之前从未听说过distinct,所以我尝试在我上面发布的同一个查询中的子查询中的选择之后简单地包含它,但它不起作用。它只返回我搜索的成分。我的整体问题有意义吗?也许我可以尝试重新措辞。抱歉,解释起来有点复杂。

以上是关于如果这些行中至少有一个具有给定值,则选择具有给定 ID 的所有行的主要内容,如果未能解决你的问题,请参考以下文章

JQuery的is()方法

在 Auto Scaling 组中,确保在给定的可用区中至少有一个 ec2 实例始终可用

GROUP BY 如果组中至少一个值满足条件,则创建组

数据库:如果任何行中的字段 X 具有值 Y,则排除“分组依据”组

如何重新排序二进制矩阵,使列中至少有“1”值

如果 ID 在任何行中具有特定值,则更改值