选择满足 SQL 中条件的元组列表

Posted

技术标签:

【中文标题】选择满足 SQL 中条件的元组列表【英文标题】:Select list of tuples that fulfills the conditions in SQL 【发布时间】:2018-02-24 11:25:23 【问题描述】:

条件:

    3 种不同的比萨饼,总价

    每个披萨必须至少有 1 位顾客 (A/B/C) 喜欢。 A、B、C 是固定要求

    (A & B & C)必须至少喜欢 3 个选定的比萨饼中的 2 个

预期结果:列出(餐厅名称、pizza1、pizza2、pizza3、总费用)

数据库架构:Customers(cname, area), Restaurants(rname, area), Pizzas(pizza), Sells(rname,pizza,price), Likes(cname, Pizza)

销售表

| rname  | Pizzas    | Price |
------------------------------
| rname1 | Hawaiian  | $10   |
| rname2 | Pepperoni | $20   |
| rname2 | Pizza3    | $20   |
| rname3 | Pizza4    | $20   |

赞表

| cname  | Pizzas   
----------------------
| A      | Hawaiian  |
| A      | Pizza3    |
| A      | Pepperoni | 
| B      | Pizza3    | 
| B      | Hawaiian  |
| C      | Hawaiian  |
| D      | Pizza4    | 

三种可能的比萨饼是夏威夷、Pizza3 和意大利辣香肠。

所以 A 必须至少喜欢 Hawaiian & Pizza3。 B 必须至少喜欢 Pizza3 和夏威夷菜,而 C 必须喜欢至少 2/3 的比萨饼,即意大利辣香肠和夏威夷菜。

A & B & C 不必喜欢同一个披萨。 但每个披萨必须至少有 1 位顾客喜欢。

SQL 查询:

SELECT s1.rname, s1.pizza, s2.pizza, s3.pizza, (s1.price+s2.price+s3.price)
FROM Sells s1 join
     Sells s2 join
     Sells s3
ON   s1.rname = s2.rname = s3. rname 
AND  s1.price < s2.price < s3.price 
WHERE s1.pizza < s2.pizza < s3.pizza 

问题:我仍然需要将likes表添加到查询中才能检查

每个比萨饼必须被 (A/B/C) 中的至少 1 人喜欢。

(A & B & C)必须至少喜欢 3 个披萨中的 2 个

数据库架构参考:http://sqlfiddle.com/#!9/dceae9/1

【问题讨论】:

是postgresql还是mysql 将标签更改为 mysql。谢谢! “A、B、C 是固定要求”是什么意思?那么“A”、“B”、“C”可以在查询中硬编码吗? 是的。它们可以被硬编码。它是固定的。例如。爱丽丝、鲍勃和克莱尔必须至少喜欢 3 个披萨中的 2 个。 【参考方案1】:

我已经开始研究这个问题,因为你上面有一个 postgresql 标记。在 PostgreSQL 中,我会尝试编写一个查询来连接 sellslikes 表,然后将它们聚合到数组中,这样你就可以将数组取消嵌套到所有可能的组合中。

我不太了解 MySQL sql 方言,所以这里有一些简单的查询(请注意,我不得不稍微更改您的数据,因为您没有任何满足所有要求的组合):

select
    s1.rname,
    s1.pizza, s2.pizza, s3.pizza,
    l1.cname, l2.cname, l3.cname,
    (s1.price+s2.price+s3.price)
from Sells as s1
    inner join Sells as s2 on
        s2.rname = s1.rname
    inner join Sells as s3 on
        s3.rname = s2.rname
    left join likes as l1 on
        l1.pizza = s1.pizza and
        l1.cname = 'alice'
    left join likes as l2 on
        l2.pizza = s2.pizza and
        l2.cname = 'bob'
    left join likes as l3 on
        l3.pizza = s3.pizza and
        l3.cname = 'james'
where
    s1.pizza <> s2.pizza and
    s3.pizza <> s2.pizza and
    s3.pizza <> s1.pizza and
    (s1.price+s2.price+s3.price) <= 80 and
    (
        l1.cname is not null and l2.cname is not null or
        l2.cname is not null and l3.cname is not null or
        l3.cname is not null and l1.cname is not null
    )

sql fiddle example

【讨论】:

帮助很大!只需要澄清最后一部分。这是为了测试 (A & B & C) 是否必须至少喜欢 3 个披萨中的 2 个,对吗? 是的,这是最后一部分。如果你对 MySQL 比较熟悉,你可以做一些更好的查询,见***.com/questions/18193365/…(这个是针对 MS SQL 的,所以我不确定它是否适用于 MySQL) 嗨,我一直在尝试找出 sql fiddle 中的代码。想知道如何使我的 rname 与众不同?因为我有太多重复项,我正在尝试添加另一个名为 s1.pricesqlfiddle.com/#!9/0b84c1/1 或者我应该在另一个问题中问它吗? :) 不,这是一个有效的观点,我稍后再看看。现在有了正确的数据,它就容易多了。所以只要你有 >= 2 个赞,你喜欢什么都没关系?

以上是关于选择满足 SQL 中条件的元组列表的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - 如何确定select查询中条件的优先级

从元组列表中返回具有最小 y 值的元组

如何将字节对象转换为 python 3 中的元组列表?

选择包含混合单引号和双引号的元组的查询

列表随机取2-元组列表

列表理解列表中的元组列表