【问题标题】:How to get Records Without Duplication Using Inner Join in SQL如何在 SQL 中使用内部联接获取不重复的记录
【发布时间】:2019-04-26 10:50:41
【问题描述】:

我正在尝试删除来自父表的重复记录,我使用自联接。那么我怎样才能摆脱父表中的重复记录。 我的表结构是这样的

ID      CategoryName    ParentID    IsActive
----+----------------+-----------+-----------
1   |   Toyota       |   NULL    |     1    
2   |   Honda        |   NULL    |     1    
3   |   Mitsubhi     |   NULL    |     1    
4   |   Toyota GLI   |     1     |     1    
5   |   Toyota XLI   |     1     |     1    
6   |   Swift        |     1     |     1    
7   |   Honda Civic  |     2     |     1    
8   |   Honda City   |     2     |     1    

我已经尝试使用 group by command & order by 进行自我加入,但它现在可以正常工作了

select a.CatogoryName,b.CatogoryName
from CategoryInfo a inner join
     CategoryInfo b
     on a.Id= b.ParentId
Group By a.CatogoryName, b.CatogoryName

结果

Category Name     Model
Honda             Honda City
Honda             Honda Civic
Toyota            Swift
Toyota            Toyota GLI
Toyota            Toyota XLI

我使用这个查询

select a.CatogoryName, b.CatogoryName
from CategoryInfo a inner join
     CategoryInfo b
     on a.Id = b.ParentId 

结果

Category Name     Model
Honda             Honda City
Honda             Honda Civic
Toyota            Swift
Toyota            Toyota GLI
Toyota            Toyota XLI

预期结果

Category Name     Model
Honda             Honda City
                  Honda Civic
Toyota            Swift
                  Toyota GLI
                  Toyota XLI

我希望单个类别名称像这样

【问题讨论】:

  • 这种类型的格式最好作为应用程序级别来完成。
  • 这是您的表示层要做的事情,而不是 SQL Server。
  • @GordonLinoff 我想在 mvc 中实现,但我得到的结果与 sql 中的结果相同,所以这就是我放置 sql 查询的原因
  • 请参考answer

标签: c# sql sql-server asp.net-mvc


【解决方案1】:

就像 Gordon Linoff 已经告诉过您的那样:您应该在您的应用程序中而不是在您的数据库中执行此操作。

这是一个为什么你的想法会引起麻烦的例子:

// Let's create a DataTable which holds the recors you want to get from the db
DataTable dt = new DataTable();
dt.Columns.Add("Category Name");
dt.Columns.Add("Model");

// Let's put in data
dt.Rows.Add(new[] { "Honda", "Honda City" });
dt.Rows.Add(new[] { null, "Honda Civic" });
dt.Rows.Add(new[] { "Toyota", "Swift" });
dt.Rows.Add(new[] { null, "Toyota GLI" });
dt.Rows.Add(new[] { null, "Toyota XLI" });

// dt is now what you want to get from your db.

// Let's see what we got:
Console.WriteLine(dt.Columns[0].ColumnName.PadRight(20) + dt.Columns[1].ColumnName.PadRight(20)); // PadRight to make it look better..
foreach (DataRow item in dt.Rows)
{
    Console.WriteLine((item[0] + "").PadRight(20) + (item[1] + "").PadRight(20));
}

我们得到了你想要的输出:

Category Name       Model
Honda               Honda City
                    Honda Civic
Toyota              Swift
                    Toyota GLI
                    Toyota XLII

但是您不能使用这些数据。让我们看看如果你用它在你的应用中做某事会发生什么:

Console.WriteLine("".PadRight(50, '-')); // Horizontal line to see 1st and 2nd output better

// Now we want to play with our data, by removing the 3rd Row:
dt.Rows.RemoveAt(2); // Index 2 is the 3rd row

// Let's see what we got after removing:
Console.WriteLine(dt.Columns[0].ColumnName.PadRight(20) + dt.Columns[1].ColumnName.PadRight(20)); // PadRight to make it look better..
foreach (DataRow item in dt.Rows)
{
    Console.WriteLine((item[0] + "").PadRight(20) + (item[1] + "").PadRight(20));
}

输出显示本田类别中的所有丰田汽车:

Category Name       Model
Honda               Honda City
                    Honda Civic
                    Toyota GLI
                    Toyota XLI

【讨论】:

  • 实际上我并没有试图通过硬编码来拟合值,它应该是动态检索
  • 请参阅上面的编辑帖子以更好地了解我的表结构
  • @kara 就在这里,你必须在服务器端处理这些事情。问题是你打算用这个结果做什么?您始终可以按类别名称分组并提取模型名称。
  • 是的,你是对的,我已经完成了应用程序级别
【解决方案2】:

"tmp" 部分——检查查询的表。你不需要它,它是给其他读者的:)

CREATE TABLE #tmpCatInfo (ID int, CategoryName varchar(55), ParentID int, IsActive int)
INSERT INTO #tmpCatInfo 
SELECT * FROM (VALUES (1, 'Toyota', NULL, 1)
                     ,(2, 'Honda', NULL, 1)
                     ,(3, 'Mitsubhi', NULL, 1)
                     ,(4, 'Toyota GLI', 1, 1)
                     ,(5, 'Toyota XLI', 1, 1)
                     ,(6, 'Swift', 1, 1)
                     ,(7, 'Honda Civic', 2, 1)
                     ,(8, 'Honda City', 2, 1)) a(ID, CategoryName, ParentID, IsActive)
;

-- USE THIS PART
-- Change #tmpCatInfo on your table name

WITH CategoryInfo (ID, CategoryName, IsActive, Model)
AS
(
SELECT ci.ID            as ID
     , ci.CategoryName  as CategoryName
     , ci2.IsActive     as IsActive
     , ci2.CategoryName as Model
FROM #tmpCatInfo ci
JOIN #tmpCatInfo ci2 ON ci.ID = ci2.ParentID
)

SELECT CASE 
         WHEN row_number() over (PARTITION BY CategoryName ORDER BY (SELECT NULL)) = 1
         THEN CategoryName
       END AS 
      CatogoryName
    , Model
FROM CategoryInfo

-- USE THIS PART

【讨论】:

  • 请参阅上面的编辑帖子以更好地了解我的表结构
  • @AbdulAleemSolutions 你好?
  • 对不起,我很忙,但是我已经完成了应用程序级别。谢谢
猜你喜欢
  • 2016-03-06
  • 1970-01-01
  • 2017-05-08
  • 2012-01-02
  • 2020-04-01
  • 2013-05-24
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
相关资源
最近更新 更多