Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:在链接表联接中获取一行_Sql - Fatal编程技术网

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列添加到示例数据中吗?与那些你需要双重加入!