尝试连接一个包含三个表连接的逗号分隔列表并获取重复项

时间:2018-02-05 21:27:29

标签: sql ssms

以下是我的表格示例:

+----------+---------------+
| txt_item | txt_unique_id |
+----------+---------------+
| Circle   |             1 |
| Square   |             2 |
| Triangle |             3 |
+----------+---------------+

tag_master

+---------+----------+
| txt_tag | opt_type |
+---------+----------+
| red     | color    |
| blue    | color    |
| yellow  | color    |
| large   | size     |
| medium  | size     |
| small   | size     |
+---------+----------+

item_tags

+---------+---------------+
| txt_tag | txt_unique_id |
+---------+---------------+
| red     |             1 |
| blue    |             1 |
| large   |             1 |
| small   |             1 |
| red     |             2 |
| yellow  |             2 |
| small   |             2 |
| medium  |             2 |
| red     |             3 |
| yellow  |             3 |
+---------+---------------+

我想要归还:

+----------+----------------------------+
| Circle   | red, blue, large, small    |
| Square   | red, yellow, small, medium |
| Triangle | red, yellow                |
+----------+----------------------------+

这就是我得到的:

+----------+---------------------------------------------+
| Circle   | red, red, red, blue, large, small, small    |
| Square   | red, red, red, yellow, yellow, small, small |
| Triangle | red, red, red, yellow, yellow               |
+----------+---------------------------------------------+

我在这里:

CREATE TABLE #screening_tags
  (
     txt_unique_id VARCHAR(36),
     tags          VARCHAR(1000)
  )

INSERT INTO #screening_tags
            (txt_unique_id,
             tags)
(SELECT txt_unique_id,
        ( STUFF((SELECT ' , ' + t.txt_tag
                 FROM   item_tags t
                        JOIN tag_master_ tm
                          ON t.txt_tag = tm.txt_tag
                        JOIN items i
                          ON t.txt_unique_id = i.txt_unique_id
                 ORDER  BY opt_type,
                           txt_tage
                 FOR xml path('')), 1, 1, '') )
 FROM   item_tags t)

SELECT *
FROM   #screening_tags

我也尝试过使用COALESCE,但我遗漏了一些东西。我需要一个DISTINCT或者其他东西,但我尝试过的所有东西都不起作用。如果我想通过opt_type进行ORDER BY,我就无法使用DISTINCT或TOP 1。感谢帮助。

5 个答案:

答案 0 :(得分:0)

尝试将连接移到tag_master上 - 查看预期结果,您不需要该表中的任何内容。实际上,您似乎不需要任何连接。

    CREATE TABLE #screening_tags
      (
         txt_unique_id VARCHAR(36),
         tags          VARCHAR(1000)
      )

    INSERT INTO #screening_tags
                (txt_unique_id,
                 tags)
    (SELECT txt_unique_id,
            ( STUFF((SELECT ' , ' + t.txt_tag
                     FROM   items i
                     where t.txt_unique_id = i.txt_unique_id
                     ORDER  BY opt_type,
                               txt_tag
                     FOR xml path('')), 1, 1, '') )
     FROM   item_tags t)

    SELECT *
    FROM   #screening_tags

答案 1 :(得分:0)

不确定您使用的是什么数据库,但是如果它是Postgres,请尝试一下:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
  <a class="navbar-brand" href="#">Angular Events</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor01"
          aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarColor01">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" [routerLink]="['/events']">All Events <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" [routerLink]="['/events/new']">Create Event</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" routerLink="" role="button" aria-haspopup="true"
           aria-expanded="false">Dropdown</a>
        <div class="dropdown-menu" x-placement="bottom-start"
             style="position: absolute; transform: translate3d(0px, 42px, 0px); top: 0px; left: 0px; will-change: transform;">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <a class="dropdown-item" href="#">Something else here</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Separated link</a>
        </div>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" placeholder="Search" type="text">
      <button class="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

SELECT i.item, string_agg(DISTINCT tm.text_tag,',') AS txt_tag_agg FROM items i INNER JOIN item_tags it ON i.txt_unique_id = it.txt_unique_id INNER JOIN tag_master tm ON it.txt_tag = tm.text_tag GROUP BY i.item 函数将构建由string_agg列分组的指定行值的聚合字符串。

答案 2 :(得分:0)

假设您使用的是SQL-server&gt; = 2017,string_agg()现已可用。

SQL Fiddle

MS SQL Server 2017架构设置

查询1

select i.txt_item , string_agg(it.txt_tag, ',')
from items i
inner join item_tags it
  on i.txt_unique_id = it.txt_unique_id
inner join tag_master tm
  on tm.txt_tag = it.txt_tag
where opt_type = 'color'
group by i.txt_item

<强> Results

| txt_item |            |
|----------|------------|
|   Circle |   red,blue |
|   Square | red,yellow |
| Triangle | red,yellow |

答案 3 :(得分:0)

使用子查询至少可以在sql server,mysql,sqlite和postgresql上工作:

select i.txt_item, 
(select string_agg(txt_tag, ',') 
from item_tags it where i.txt_unique_id=it.txt_unique_id) as txt_tag
from items i

返回:

txt_item    txt_tag
Circle      red,blue,large,small
Square      red,yellow,small,medium
Triangle    red,yellow

在mysql上使用group_concat(txt_tag)而不是string_agg。 在postgres上,使用array_agg(txt_tag)。

sqlfiddle.com

答案 4 :(得分:0)

我想通了 - 我必须将STUFF子查询链接到WHERE子句中的主查询

CREATE TABLE #screening_tags
  (
     txt_unique_id VARCHAR(36),
     tags          VARCHAR(1000)
  )

INSERT INTO #screening_tags
            (txt_unique_id,
             tags)
(SELECT txt_unique_id,
        ( STUFF((SELECT ', ' + t.txt_tag
                 FROM   item_tags t1
                       WHERE t.txt_unique_id = t2.txt_unique_id
                 FOR xml path('')), 1, 1, '') )
 FROM   item_tags t2)

SELECT *
FROM   #screening_tags

+----------+----------------------------+
| Circle   | red, blue, large, small    |
| Square   | red, yellow, small, medium |
| Triangle | red, yellow                |
+----------+----------------------------+