2009-02-13 37 views
12

Tôi có 5 cột tương ứng với câu trả lời trong một cơ sở dữ liệu đố trò chơi - phải, wrong1, wrong2, wrong3, wrong4Chọn biệt từ nhiều lĩnh vực sử dụng sql

Tôi muốn trả lại tất cả câu trả lời tốt mà không bản sao. Tôi đã hy vọng để thực hiện điều này mà không cần sử dụng một bảng tạm thời. Có thể sử dụng một cái gì đó tương tự như thế này không ?:

select c1, c2, count(*) 
from t 
group by c1, c2 

Nhưng điều này trả về 3 cột. Tôi muốn một cột câu trả lời khác biệt.

Cảm ơn thời gian của bạn

Trả lời

15

Điều này sẽ cung cấp cho bạn tất cả các giá trị khác biệt từ bảng. Tôi đoán bạn muốn thêm các mệnh đề để chỉ chọn cho một câu hỏi cụ thể. Tuy nhiên, giải pháp này yêu cầu 5 truy vấn con và có thể chậm nếu bảng của bạn rất lớn.

SELECT DISTINCT(ans) FROM (
    SELECT right AS ans FROM answers 
    UNION 
    SELECT wrong1 AS ans FROM answers 
    UNION 
    SELECT wrong2 AS ans FROM answers 
    UNION 
    SELECT wrong3 AS ans FROM answers 
    UNION 
    SELECT wrong4 AS ans FROM answers 
) AS Temp 
+1

điều này có vẻ tốt. Tôi sẽ thử nó ngay bây giờ. – Bryan

+0

Hãy thử một trong những trục tôi chỉ làm dưới đây. Tôi nghĩ điều đó tốt hơn nhiều. Tôi đã đọc về những gì hiệu quả hơn mặc dù, tôi không biết quá nhiều về hoạt động nội bộ của các máy chủ cơ sở dữ liệu khác nhau. – achinda99

+0

Rực rỡ. Ước gì tôi nghĩ về điều đó. –

1

Đây có phải là những gì bạn muốn không?

select distinct c1 from t

+1

Khó để biết nó có phải không, nhưng 1 có vẻ như nó phải là :) –

+0

yea thật khó để nói – JoshBerke

+0

Không, chọn riêng biệt với một cột – Bryan

2

Vâng, bạn có thể sử dụng một UNION và chạy 5 câu chọn, một cho mỗi cột trong bảng. Nó sẽ trông giống như sau:

SELECT right FROM answers 
UNION 
SELECT wrong1 FROM answers 
UNION 
SELECT wrong2 FROM answers 
UNION 
SELECT wrong3 FROM answers 
UNION 
SELECT wrong4 FROM answers 

Điều này sẽ cung cấp cho bạn một danh sách chứa tất cả câu trả lời. Tuy nhiên, bạn vẫn sẽ có các bản sao nếu bạn có nhiều bản sao của cùng một câu trả lời trong một cột.

0

Trong MySQLMS SQL:

SELECT 
     CASE 
     WHEN which = 1 THEN c1 
     WHEN which = 2 THEN c2 
     WHEN which = 3 THEN c3 
     WHEN which = 4 THEN c4 
     WHEN which = 5 THEN c5 
     END AS answer, 
     which 
FROM mytable, (
    SELECT 1 AS which 
    UNION ALL 
    SELECT 2 
    UNION ALL 
    SELECT 3 
    UNION ALL 
    SELECT 4 
    UNION ALL 
    SELECT 5 
) w 

Đối Oracle, thêm FROM DUAL cho mỗi số lựa chọn.

5

Tôi đã cung cấp một câu trả lời above.

Tuy nhiên tôi đã tìm ra cách tốt hơn để sử dụng UNPIVOT.

SELECT DISTINCT(ans) 
FROM (
    SELECT [Name], ANS 
    FROM (
     SELECT right, wrong1, wrong2, wrong3, wrong4 
     FROM answers 
    ) AS PVT 
    UNPIVOT 
    (ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT 
) AS OUTPUT; 

Bạn có thể cung cấp bất kỳ mệnh đề WHERE trong subquery nội bộ:

SELECT DISTINCT(ans) 
FROM (
    SELECT [Name], ANS 
    FROM (
     SELECT right, wrong1, wrong2, wrong3, wrong4 
     FROM answers 
     WHERE (...) 
    ) AS PVT 
    UNPIVOT 
    (ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT 
) AS OUTPUT; 
+0

tại sao điều này tốt hơn nhiều? – Bryan

+0

Tôi thích cái này tốt hơn vì logic, tôi đang làm những gì tôi muốn làm. Truy vấn đầu tiên chỉ đạt được nó, nơi mà điều này theo sau quá trình mặc dù của tôi. Ngoài ra, ít truy vấn con hơn. – achinda99

8
SELECT DISTINCT(ans) FROM (
    SELECT right AS ans FROM answers 
    UNION 
    SELECT wrong1 AS ans FROM answers 
    UNION 
    SELECT wrong2 AS ans FROM answers 
    UNION 
    SELECT wrong3 AS ans FROM answers 
    UNION 
    SELECT wrong4 AS ans FROM answers 
) AS Temp 

Các DISTINCT là không cần thiết, bởi vì UNION sẽ không trả lại hàng mà là giống hệt nhau cho tất cả các cột. (Khi bạn muốn trùng lặp, hoặc nếu bạn biết rằng không có bản sao tồn tại, sử dụng UNION ALL cho hiệu suất nhanh hơn)

này sẽ cung cấp cho bạn một danh sách duy nhất chứa tất cả các câu trả lời. Tuy nhiên, bạn vẫn sẽ có các bản sao nếu bạn có nhiều bản sao của cùng một câu trả lời trong một cột.

Đó không phải là trường hợp nếu bạn sử dụng UNION, chỉ khi bạn sử dụng UNION ALL

SELECT [value] INTO #TEMP 
FROM 
(
SELECT [value] = 1 
UNION ALL SELECT 2 
UNION ALL SELECT 3 
UNION ALL SELECT 1 
) AS X 

(4 row(s) affected) 

SELECT [value] 
FROM #TEMP 

value  
----------- 
1 
2 
3 
1 

(4 row(s) affected) 

SELECT [value] 
FROM #TEMP 
UNION 
SELECT [value] 
FROM #TEMP 

value  
----------- 
1 
2 
3 

(3 row(s) affected) 
+0

Vâng, bạn nói đúng. Tôi đã sai về điều đó. Tôi đã thử nghiệm cả hai và nó đã cho tôi kết quả tương tự trên tập dữ liệu của tôi nhưng tôi không chắc chắn về các chi tiết cụ thể vì vậy nếu có trùng lặp DISTINCT đã có thể chăm sóc nó. Tôi chưa bao giờ sử dụng một UNION trong bất kỳ công việc thực tế nào tôi đã làm. Chỉ mục đích giáo dục. – achinda99

+0

Bạn chính xác! Khác biệt không cần thiết. – Bryan

+0

Đừng lo! Đáng ghi nhớ để luôn luôn sử dụng UNION ALL khi bạn biết rằng không có bản sao (hoặc bạn MUỐN bất kỳ bản sao). Lưu máy chủ phải thực hiện SORT và De-DUPE – Kristen

0

Đây là câu trả lời chính xác.

SELECT (ans) FROM (
    SELECT correct AS ans FROM tGeoQuiz 
    UNION 
    SELECT wrong1 AS ans FROM tGeoQuiz 
    UNION 
    SELECT wrong2 AS ans FROM tGeoQuiz 
    UNION 
    SELECT wrong3 AS ans FROM tGeoQuiz 
    UNION 
    SELECT wrong4 AS ans FROM tGeoQuiz 
) AS Temp 
2

Cột "đúng, sai1, sai2, sai3, sai4" có nghĩa là bạn có cơ sở dữ liệu được thiết kế sai. Nói chung, hậu tố số hoặc chữ cái trên tên cột phải là cờ đỏ để suy nghĩ lại vấn đề.

Như bạn đã quan sát, thiết kế của bạn yêu cầu bạn phải hack xung quanh để nhận giải pháp cho vấn đề giảm dữ liệu điển hình.

+0

Bạn là một người goofball. Đối với một bài kiểm tra đơn giản không có gì sai với việc tạo ra một bảng câu hỏi nhanh. Cố gắng để âm thanh thông minh hơn ... chúng tôi là chúng ta? – Bryan

Các vấn đề liên quan