SQL - 如何跨多个表

时间:2016-06-22 08:27:19

标签: sql sql-server sql-server-2008

我有一个包含以下两个表的数据库 - DepartmentsOperations

Departments的关键值是:

DEPT_REF
DEPT_NAME
DEPT_FUNCTION

Operations的关键值是:

OPS_REF
OPS_NAME
DEPT_REF

我需要解决的是一个查询,它会为我提供Operations.OPS_NAMEDepartments.DEPT_NAMEDepartments.DEPT_FUNCTION的列表,它们是重复的,但应该忽略大小写。理想情况下,它也应该有一个计数。

例如:

Departments

+----------+-----------+---------------+
| DEPT_REF | DEPT_NAME | DEPT_FUNCTION |
+----------+-----------+---------------+
| 0001     | Home      | Live here     |
+----------+-----------+---------------+
| 0002     | HOME      | LIVE HERE     |
+----------+-----------+---------------+
| 0003     | HOME      | Live here     |
+----------+-----------+---------------+
| 0004     | work      | Work Here     |
+----------+-----------+---------------+
| 0005     | Work      | Work Here     |
+----------+-----------+---------------+
| 0006     | OTHER     | Other Stuff   |
+----------+-----------+---------------+

Operations

+---------+----------+----------+
| OPS_REF | OPS_NAME | DEPT_REF |
+---------+----------+----------+
| 000A    | OPS1     | 0001     |
+---------+----------+----------+
| 000B    | Ops1     | 0001     |
+---------+----------+----------+
| 000C    | ops1     | 0002     |
+---------+----------+----------+
| 000D    | OPS2     | 0003     |
+---------+----------+----------+
| 000E    | ops2     | 0001     |
+---------+----------+----------+
| 000F    | ops2     | 0004     |
+---------+----------+----------+
| 000G    | OPS3     | 0004     |
+---------+----------+----------+
| 000H    | OPS3     | 0005     |
+---------+----------+----------+

我正在寻找的输出是一个操作名称,部门名称和部门功能的列表,以大写形式显示并带有计数。因此,我希望看到示例数据:

+----------+-----------+---------------+-------+
| OPS_NAME | DEPT_NAME | DEPT_FUNCTION | COUNT |
+----------+-----------+---------------+-------+
| OPS1     | HOME      | LIVE HERE     | 3     |
+----------+-----------+---------------+-------+
| OPS2     | HOME      | LIVE HERE     | 2     |
+----------+-----------+---------------+-------+

在单个表中查找重复项是没有问题的,但我不知道从多个表开始执行该操作,必须忽略大小写。

3 个答案:

答案 0 :(得分:5)

如果你需要分开OPS_NAME的大小写,你可以使用 将它们转换为二进制数据类型:

SELECT  UPPER(o.OPS_NAME) as OPS_NAME,
        UPPER(d.DEPT_NAME) as DEPT_NAME,
        UPPER(d.DEPT_FUNCTION) as DEPT_FUNCTION,
        COUNT(DISTINCT CAST(o.OPS_NAME As BINARY)) AS [COUNT]
FROM Departments d
INNER JOIN Operations o
    ON o.DEPT_REF = d.DEPT_REF
GROUP BY o.OPS_NAME,
        d.DEPT_NAME,
        d.DEPT_FUNCTION
HAVING COUNT(DISTINCT CAST(o.OPS_NAME As BINARY)) > 1

输出:

OPS_NAME    DEPT_NAME   DEPT_FUNCTION   COUNT
OPS1        HOME        LIVE HERE       3
OPS2        HOME        LIVE HERE       2

修改

您还可以使用COUNT(DISTINCT o.OPS_NAME COLLATE Latin1_General_CS_AS)  正如评论中所述。在您的情况下,COUNT(DISTINCT BINARY_CHECKSUM(o.OPS_NAME))也可以正常工作,但在某些情况下可能会重复。

答案 1 :(得分:3)

符合ANSI SQL的答案(在派生表中执行UPPER()):

select OPS_NAME, DEPT_NAME, DEPT_FUNCTION, count(OPS_REF)
from
(
    SELECT UPPER(o.OPS_NAME) as OPS_NAME,
           UPPER(d.DEPT_NAME) as DEPT_NAME,
           UPPER(d.DEPT_FUNCTION) as DEPT_FUNCTION,
           o.OPS_REF as OPS_REF
    FROM Departments d
    INNER JOIN Operations o
        ON o.DEPT_REF = d.DEPT_REF
) dt
GROUP BY OPS_NAME,
         DEPT_NAME,
         DEPT_FUNCTION

HAVING count(OPS_REF) > 1

但我宁愿建议另一种方法,定义列以使用不区分大小写的排序规则!然后分组/比较等将自动运行! (即不需要UPPER()。)

答案 2 :(得分:2)

案件不应该成为一个问题。为了演示的目的,我已将数据转换为大写。

测试数据;

IF OBJECT_ID('tempdb..#Departments') IS NOT NULL DROP TABLE #Departments
GO
CREATE TABLE #Departments (DEPT_REF varchar(4), DEPT_NAME varchar(5), DEPT_FUNCTION varchar(11))
INSERT INTO #Departments (DEPT_REF, DEPT_NAME, DEPT_FUNCTION)
VALUES
 ('0001','Home','Live here')
,('0002','HOME','LIVE HERE')
,('0003','HOME','Live here')
,('0004','work','Work Here')
,('0005','Work','Work Here')
,('0006','OTHER','Other Stuff')

IF OBJECT_ID('tempdb..#Operations') IS NOT NULL DROP TABLE #Operations
GO
CREATE TABLE #Operations (OPS_REF varchar(4), OPS_NAME varchar(4), DEPT_REF varchar(4))
INSERT INTO #Operations (OPS_REF, OPS_NAME, DEPT_REF)
VALUES
 ('000A','OPS1','0001')
,('000B','Ops1','0001')
,('000C','ops1','0002')
,('000D','OPS2','0003')
,('000E','ops2','0001')
,('000F','ops2','0004')
,('000G','OPS3','0004')
,('000H','OPS3','0005')

实际查询

SELECT 
UPPER(o.OPS_NAME) OPS_NAME
,UPPER(d.DEPT_NAME) DEPT_NAME
,UPPER(d.DEPT_FUNCTION) DEPT_FUNCTION
,COUNT(d.DEPT_NAME) COUNT
FROM #Operations o
LEFT JOIN #Departments d
ON o.DEPT_REF = d.DEPT_REF
GROUP BY o.OPS_NAME, d.DEPT_NAME, d.DEPT_FUNCTION
HAVING COUNT(d.DEPT_NAME) > 1

结果

OPS_NAME    DEPT_NAME   DEPT_FUNCTION   COUNT
OPS1        HOME        LIVE HERE       3
OPS2        HOME        LIVE HERE       2
OPS3        WORK        WORK HERE       2