SQL:在链接表联接中获取一行
假设我有两张表,SQL:在链接表联接中获取一行,sql,Sql,假设我有两张表,食物和人,我用链接表指示谁喜欢哪种食物。因此: foods ----- sausages pie Mars bar people ------ john paul george ringo person | food (link table) -------+----- john | pie john | sausage paul | sausage 我想要一份食物清单,以及一个喜欢那种食物的人。我想要一张这样的桌子: food | a randomly
食物
和人
,我用链接表指示谁喜欢哪种食物。因此:
foods
-----
sausages
pie
Mars bar
people
------
john
paul
george
ringo
person | food (link table)
-------+-----
john | pie
john | sausage
paul | sausage
我想要一份食物清单,以及一个喜欢那种食物的人。我想要一张这样的桌子:
food | a randomly chosen liker
---------+------------------------
sausage | john (note: this could be "paul" instead)
pie | john (note: must be john; he's the only liker)
Mars bar | null (note: nobody likes it)
是否可以在一个查询中执行此操作
显然,我可以做到:
select
f.food, p.person
from
food f inner join link l
on f.food = l.food
inner join person p
on l.person = p.person
但是那会给我两排香肠,因为有两个人喜欢,我必须自己去重复这些排。做
左连接
也能得到没人喜欢的食物<代码>分组方式要仅获取每种食物一次,请使用MIN
选择第一个喜欢该食物的人
select f.food, min(p.person)
from food f
left join linktable l on f.id = l.food_id
left join people p on p.id = l.person_id
group by f.food
做
LEFT JOINs
也能得到没人喜欢的食物<代码>分组方式要仅获取每种食物一次,请使用MIN
选择第一个喜欢该食物的人
select f.food, min(p.person)
from food f
left join linktable l on f.id = l.food_id
left join people p on p.id = l.person_id
group by f.food
另一种变体。。(假设它是SQL Server)
另一种变体。。(假设它是SQL Server)
我会使用一个分区来实现这一点,例如:
WITH ORDERED AS
(
SELECT
PERSON,
FOOD,
ROW_NUMBER() OVER (PARTITION BY lower(FOOD) ORDER BY lower(PERSON) DESC) AS RN
FROM
(
SELECT 'john' AS PERSON ,'pie' AS FOOD FROM DUAL UNION
SELECT 'john1' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john2' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john3' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john4' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john5' AS PERSON ,'eggs' AS FOOD FROM DUAL UNION
SELECT 'john6' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'dada' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'paul' AS PERSON ,'sausage' AS FOOD FROM DUAL
-- Your select statement here that links the two tables
) PERSON_FOOD
)
SELECT
FOOD,
PERSON
FROM
ORDERED
WHERE
RN = 1
这将为您提供以下信息:
FOOD | PERSON
-------------------
eggs | john
pie | john
sausage | paul
这是在oracle语法中我将使用分区来实现,例如:
WITH ORDERED AS
(
SELECT
PERSON,
FOOD,
ROW_NUMBER() OVER (PARTITION BY lower(FOOD) ORDER BY lower(PERSON) DESC) AS RN
FROM
(
SELECT 'john' AS PERSON ,'pie' AS FOOD FROM DUAL UNION
SELECT 'john1' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john2' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john3' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john4' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john5' AS PERSON ,'eggs' AS FOOD FROM DUAL UNION
SELECT 'john6' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'dada' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'paul' AS PERSON ,'sausage' AS FOOD FROM DUAL
-- Your select statement here that links the two tables
) PERSON_FOOD
)
SELECT
FOOD,
PERSON
FROM
ORDERED
WHERE
RN = 1
这将为您提供以下信息:
FOOD | PERSON
-------------------
eggs | john
pie | john
sausage | paul
这是在oracle语法中您需要为选择列表中的p.person使用聚合函数。您需要删除单个
p.person
,并且只需保留min(p.person)
。您需要为选择列表中的p.person使用聚合函数。您需要删除单个p.person
,并且,只需保留min(p.person)
。我会将食物id和人员id存储在链接表中。(名字只存储一次,在食物或人表中。存储id在其他地方。)@jarlh我实际上是在链接表中存储id;以上内容经过简化,便于阅读。:-)您不能将id列添加到示例数据中吗?与那些你需要双重加入!我会将食物id和人id存储在链接表中。(名字只存储一次,在食物或人表中。存储id在其他地方。)@jarlh我实际上是在链接表中存储id;以上内容经过简化,便于阅读。:-)您不能将id列添加到示例数据中吗?与那些你需要双重加入!