2012-12-04 36 views
15

Tôi đang cố gắng so sánh hai địa chỉ từ cùng một ID để xem chúng có khớp không. Ví dụ:Tìm những hàng nào có các giá trị khác nhau cho một cột nhất định trong SQL

Id Adress Code  Address 
1 1    123 Main 
1 2    123 Main 
2 1    456 Wall 
2 2    456 Wall 
3 1    789 Right 
3 2    100 Left 

Tôi chỉ đang cố gắng tìm hiểu xem địa chỉ cho mỗi ID có phù hợp hay không. Vì vậy, trong trường hợp này tôi muốn quay trở lại chỉ ID 3 như có một địa chỉ khác nhau cho Địa chỉ Mã 1 và 2.

+2

Cool! Bạn đã thử cái gì? –

+0

RDBMS nào? Nếu SQL Server, hãy thử xem [câu hỏi này] (http://stackoverflow.com/q/510916/1220971). – Bridge

+0

Rất tiếc, tôi đang sử dụng tính năng này trong Teradata. –

Trả lời

23

Tham gia bảng đó và cung cấp cho nó hai bí danh khác nhau (A và B) . Điều này cho phép so sánh các hàng khác nhau của cùng một bảng.

SELECT DISTINCT A.Id 
FROM 
    Address A 
    INNER JOIN Address B 
     ON A.Id = B.Id AND A.[Adress Code] < B.[Adress Code] 
WHERE 
    A.Address <> B.Address 

So sánh "ít hơn" < đảm bảo bạn nhận được 2 địa chỉ khác nhau và bạn không nhận được 2 mã địa chỉ giống nhau hai lần. Sử dụng "không bằng" <> thay vào đó, sẽ mang lại các mã như (1, 2) và (2, 1); mỗi người trong số họ cho bí danh A và bí danh B lần lượt.

Điều khoản tham gia chịu trách nhiệm cho việc ghép nối các hàng trong đó điều khoản where kiểm tra các điều kiện bổ sung.


CẬP NHẬT:

Các truy vấn trên làm việc với bất kỳ mã địa chỉ. Nếu bạn muốn so sánh địa chỉ bằng mã địa chỉ cụ thể, bạn có thể thay đổi các truy vấn để

SELECT A.Id 
FROM 
    Address A 
    INNER JOIN Address B 
     ON A.Id = B.Id 
WHERE      
    A.[Adress Code] = 1 AND 
    B.[Adress Code] = 2 AND 
    A.Address <> B.Address 

Tôi tưởng tượng rằng điều này có thể hữu ích để tìm kiếm khách hàng có địa chỉ thanh toán (Địa chỉ Mã = 1 là một ví dụ) khác nhau từ địa chỉ giao hàng (Mã địa chỉ = 2).

+1

Tuyệt vời, cảm ơn rất nhiều! –

+0

wow, rất cleaver. Cảm ơn bạn đã đưa ra cả hai ví dụ. – JoshYates1980

0

Cá nhân, tôi sẽ in chúng vào một tập tin sử dụng Perl hoặc Python trong các định dạng

<COL_NAME>: <COL_VAL> 

cho mỗi hàng sao cho tệp có nhiều dòng như có cột. Sau đó, tôi sẽ làm một diff giữa hai tập tin, giả sử bạn đang trên Unix hoặc so sánh chúng bằng cách sử dụng một số utilty tương đương trên hệ điều hành khác. Nếu bạn có nhiều bản ghi (tức là nhiều hàng), tôi sẽ thêm vào mỗi hàng tệp và sau đó tệp sẽ có NUM_DB_ROWS * NUM_COLS dòng

+2

-1. Lấy làm tiếc.Dumping dữ liệu SQL ra một tập tin bên ngoài để khác với Perl hoặc Python chỉ là sai; "Tôi biết cách sử dụng cái búa này, nên hãy đối xử với mọi thứ như móng tay". Giải pháp không giải quyết được câu hỏi được hỏi, đó là cách thực hiện ** trong SQL **. –

+0

Lợi thế của việc viết một kịch bản để làm điều đó là nó có thể được làm việc cho bất kỳ bảng nào mà không cần phải chỉ định các tên cột vì chúng có thể được đọc từ các bảng hệ thống. Tôi đã viết một vài kịch bản như thế này cho các QAs, những người phải so sánh các tập bản ghi trên các cơ sở dữ liệu khác nhau, nơi chỉ SQL không đủ và thậm chí nếu nó đã làm, họ sẽ phải viết một truy vấn tùy chỉnh cho mỗi bảng khác nhau để phản ánh các cột khác nhau. Dữ liệu bảng cụ thể duy nhất trong các tập lệnh của tôi, ngoài ra, tất nhiên, các chi tiết bảng như tên, lược đồ và máy chủ, sẽ là chuỗi tiêu chí. – amphibient

+0

Nhưng so với việc đánh vần từng tên cột, đó là cấu hình tùy chỉnh tương đối ít. SQL là một công cụ tuyệt vời nhưng có những hạn chế vững chắc được khắc phục tốt hơn bên ngoài nó (trong những thứ như các ngôn ngữ kịch bản) hơn là các câu lệnh SQL giống như một máy Rube Goldberg. Tôi thích sự sạch sẽ, cấu trúc và sự đơn giản. Bạn có thể giữ cho downvote của bạn, tôi không yêu cầu bạn thay đổi điều này, việc xây dựng này là nhiều hơn triết lý của tôi với phần còn lại của thế giới – amphibient

1

Bạn có thể làm điều này bằng cách sử dụng nhóm theo:

select id, addressCode 
from t 
group by id, addressCode 
having min(address) <> max(address) 

Một cách khác để viết thư này có vẻ rõ ràng hơn, nhưng không thực hiện cũng như:

select id, addressCode 
from t 
group by id, addressCode 
having count(distinct address) > 1 
3

này làm việc cho PL/SQL:

select count(*), id,address from table group by id,address having count(*)<2 
Các vấn đề liên quan