简体   繁体   English

mysql 中的多个连接与 3 个表

[英]Multiple joins in mysql with 3 tables

i have 3 tables我有 3 张桌子

branch-
  br_id,
  br_name

users 
 user_id
 user_name
 user_type (2 types 'owner' 'admin')
 user_branch (associated branch )
 user_branches (comma seperated branch ids in case of 'admin' type )

item 
  it_id
  it_amount
  it_owner
  it_admin 
  it_activated

Here each item is owned by as user type "owner"这里每个项目都由用户类型“所有者”拥有

Each item is also associated by a user type "admin"每个项目还与用户类型“admin”相关联

what I want is list of branches and associated total amount and total count我想要的是分支机构列表以及相关的总金额和总数

**Branch**             **total**  **total amount**
some branch Name    5   500
another Branch Name 7   780

How can i do it in single query我怎样才能在单个查询中做到这一点

i tried this which is showing amount of all branches我试过这个,它显示了所有分支的数量

SELECT br_name,
count(it_id),
SUM(it_amount),
FROM branch
LEFT JOIN users ON FIND_IN_SET(br_id,user_branches)>0
LEFT JOIN item ON it_admin=ad_id
WHERE it_activated=1
GROUP BY br_name

but I am getting same count and amount in all branches但我在所有分支机构都得到相同的数量和数量

First, you should really provide bare minimums, especially when asking with bounty.首先,您应该真正提供最低限度,尤其是在询问赏金时。 Not knowing your table structures and sample content makes it harder for others to assist.不了解您的表格结构和示例内容会使其他人更难提供帮助。 I have created sample create tables and inserts, then the query.我创建了示例创建表和插入,然后是查询。 Correct me if anything is inaccurate.如果有任何不准确之处,请纠正我。

CREATE TABLE branch (
  br_id int unsigned NOT NULL,
  br_name varchar(10) NOT NULL,
  PRIMARY KEY (br_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE users (
  user_id int unsigned NOT NULL,
  user_name varchar(10) NOT NULL,
  user_type varchar(10) NOT NULL,
  user_branch int NOT NULL,
  user_branches varchar(10) NOT NULL,
  PRIMARY KEY (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE item (
  it_id int unsigned NOT NULL,
  it_amount int NOT NULL,
  it_owner int NOT NULL,
  it_admin int NOT NULL,
  it_activated int NOT NULL,
  PRIMARY KEY (it_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into branch ( br_id, br_name )
  values 
  ( 1, 'b1' ), 
  ( 2, 'b2'), 
  ( 3, 'b3' );

insert into users ( user_id, user_name, user_type, user_branch, user_branches )
  values 
  ( 1, 'n1', 'owner', 1, '' ),
  ( 2, 'n2', 'admin', 2, '2, 3' ),
  ( 3, 'n3', 'owner', 3, '' );

insert into item ( it_id, it_amount, it_owner, it_admin, it_activated )
  values
  ( 1, 100, 1, 2, 1 ),
  ( 2, 150, 3, 2, 1 ),
  ( 3, 125, 1, 2, 1 ),
  ( 4, 30, 3, 2, 0 );

Now, what I believe you need is a UNION query covering individually the owner vs the admin, otherwise, you will be getting double-counts across the board.现在,我认为您需要的是一个 UNION 查询,分别涵盖所有者和管理员,否则,您将得到全面的双重计算。 Secondly, I believe not the greatest layout of table design whenever you are using a comma separated list to hold multiple IDs that someone/something can qualify under, such as your ADMIN users.其次,当您使用逗号分隔的列表来保存某人/某物可以符合条件的多个 ID(例如您的 ADMIN 用户)时,我认为这不是最好的表格设计布局。 But if that is what you have and cant change it, so be it.但如果那是你所拥有的并且无法改变它,那就这样吧。

So, now on with the query.所以,现在继续查询。 Look at each one individually.逐一查看。 If doing the query by the OWNER type of user, join just on that user type and tie exclusively to the user's branch, then tie to the item table based on the item's owner.如果按 OWNER 类型的用户进行查询,则仅加入该用户类型并专门绑定到用户的分支,然后根据项目的所有者绑定到项目表。 You get one result.你得到一个结果。

Finally, similar join, but only based on the ADMIN type of user, and join to the item based on the item's ADMIN ID.最后,类似的加入,但仅基于用户的 ADMIN 类型,并根据项目的 ADMIN ID 加入项目。

Again, without your sample source records and expected output, this is the best interpretation I can come up with (and probably others too) at this time.同样,如果没有您的示例源记录和预期的 output,这是我目前(可能还有其他人)能想到的最佳解释。 So, with the queries in a similar column result structure they can be brought together with a "UNION".因此,对于类似列结果结构中的查询,它们可以与“UNION”组合在一起。 I added an additional column to show the origin of the numbers as based on the Source of owner/admin respectively.我添加了一个额外的列来显示数字的来源,分别基于所有者/管理员的来源。

select
        b.br_name,
        'By Owner' Source,
        count(i.it_id) numOfItems,
        SUM(i.it_amount) sumOfAmount
    FROM
        branch b
            JOIN Users u
                on u.user_type = 'owner'
                AND b.br_id = u.user_branch
                JOIN Item i
                    on u.user_id = i.it_owner
                    AND i.it_activated = 1
    group by
        b.br_name
UNION        
select
        b.br_name,
        'By Admin' Source,
        count(i.it_id) numOfItems,
        SUM(i.it_amount) sumOfAmount
    FROM
        branch b
            JOIN Users u
                on u.user_type = 'admin'
                AND FIND_IN_SET(b.br_id, u.user_branches) > 0
                JOIN Item i
                    on u.user_id = i.it_admin
                    AND i.it_activated = 1
    group by
        b.br_name;
        

I am not sure what you want from the query, so I have taken a guess.我不确定你想从查询中得到什么,所以我猜测了一下。 My answer query finds the total count and totaled amounts for the items linked to each branch, first by owner and then by admins.我的答案查询查找链接到每个分支的项目的总计数和总金额,首先按所有者,然后按管理员。

In your query, you have a field "ad_id":在您的查询中,您有一个字段“ad_id”:

    LEFT JOIN item ON it_admin=ad_id

I assume that is meant to be "user_id"?我认为这意味着“user_id”?

I also notice that, in your query, you have not referenced the owners at all.我还注意到,在您的查询中,您根本没有引用所有者。 If you are in fact looking for the results from items linked to branches just by the admins, then you can just remove/ignore the first two subqueries in the following query:如果您实际上是仅由管理员从链接到分支的项目中查找结果,那么您可以删除/忽略以下查询中的前两个子查询:

       SELECT   br_name as branchname,
            (SELECT COUNT( DISTINCT it_id) 
                FROM item i1 
                JOIN users u1 ON i1.it_owner = u1.user_id AND i1.it_activated=1
                WHERE u1.user_branch = b.br_id AND u1.user_type = "owner") as ownertotal,
            (SELECT COUNT( DISTINCT it_id) 
                FROM item i2 
                JOIN users u2 ON i2.it_admin = u2.user_id AND i2.it_activated=1
                WHERE FIND_IN_SET(b.br_id, u2.user_branches) != 0 AND u2.user_type = "admin") as admintotal ,
            (SELECT SUM(i3.it_amount) 
                FROM item i3 
                JOIN users u3 ON i3.it_owner = u3.user_id AND i3.it_activated=1
                WHERE u3.user_branch = b.br_id AND u3.user_type = "owner") as owneramount,
            (SELECT SUM(i4.it_amount) 
                FROM item i4 
                JOIN users u4 ON i4.it_admin = u4.user_id AND i4.it_activated=1
                WHERE FIND_IN_SET(b.br_id, u4.user_branches) != 0 AND u4.user_type = "admin") as adminamount
    FROM branch b;

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

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