tags:

views:

68

answers:

5

what is wrong with this query? each one of them works separately but they're not working after i write the select *

select * from 
(SELECT     COUNT(issuer_id) AS INSU_cnt, min_desc AS INSURANCE
FROM         issuer INNER JOIN code ON economy_sect = cod_id
WHERE     (min_desc = 't')
GROUP BY min_desc)
UNION 
(SELECT     COUNT(issuer_id) AS Bank_cnt,min_desc AS BANKS
FROM         issuer INNER JOIN code ON economy_sect = cod_id
WHERE     (min_desc = 'b')
GROUP BY min_desc
)

edit: I guess the problem is that I have all the data I want in one table (with a query) and I want to select 5 rows from that table... I have this table:

Name        Count
Bank        20
Insurance  10
Econ        10

and I want the select statement to be something like this: select bank_count, insurance_count, econ_count and I thought a union might solve my problem, but it doesn't make much sense...

+2  A: 

Instead of a UNION, use a IN clause, like this:

SELECT COUNT(issuer_id) AS Count, min_desc
FROM issuer INNER JOIN code ON economy_sect = cod_id
WHERE min_desc IN('t', 'b')
GROUP BY min_desc

With the UNION approach you're only going to get the column named from the first query anyway, so since that's already gone you might as well do it in a single query :)


For your updated question: this varies based on which database you're using, but something like a CASE statement would work:

SELECT (CASE min_desc WHEN 't' THEN 'Insurance'
                      WHEN 'b' THEN 'Bank'
                      WHEN 'e' THEN 'Econ'
                      ELSE 'Other'
        End) as Name, COUNT(issuer_id) AS Count
FROM issuer INNER JOIN code ON economy_sect = cod_id
WHERE min_desc IN('t', 'b')
GROUP BY min_desc

Or if you had a description table you could join to it gets cleaner/more maintainable...there are several ways to approach this problem, I'm not sure what your options or platform are.

Nick Craver
+1 for avoiding union.
Yves M.
+1 for avoiding union. Changing ` COUNT(issuer_id) AS Count` to `CASE min_desc WHEN 't' THEN COUNT(issuer_id) ELSE 0 END AS Insu_Cnt, CASE min_desc WHEN 'b' THEN COUNT(issuer_id) ELSE 0 END AS Bank_Cnt` would give separate columns for Bank and Insurance values, as required by MNA.
Mark Bannister
+1  A: 

I think the specific problem with the query that you posted is that you need parentheses:

SELECT * FROM (
    (
        SELECT    COUNT(issuer_id) AS INSU_cnt, min_desc AS INSURANCE
        FROM      issuer INNER JOIN code ON economy_sect = cod_id
        WHERE     min_desc = 't'
        GROUP BY  min_desc
    )
    UNION 
    (
        SELECT    COUNT(issuer_id) AS Bank_cnt, min_desc AS BANKS
        FROM      issuer INNER JOIN code ON economy_sect = cod_id
        WHERE     min_desc = 'b'
        GROUP BY  min_desc
    )
) T1

However this query is not actually what you want to do. What you actually want to do is this:

SELECT
(
    SELECT COUNT(issuer_id)
    FROM issuer INNER JOIN code ON economy_sect = cod_id
    WHERE min_desc = 't'
) AS ins_cnt,
    SELECT COUNT(issuer_id)
    FROM issuer INNER JOIN code ON economy_sect = cod_id
    WHERE min_desc = 'b'
) AS bank_cnt
Mark Byers
with one query I can get all the information that i need, but what i want is the information in each row separately.for example i get:row1: banks 20row2: insurance 10....and I want the query to return bank_cnt(20), ins_cnt(10), ...How can I do this?
MNA
@MNA: You want the result as a string? Your comment is also hard to read because the formatting got messed up.
Mark Byers
@MNA: I reread your comment several times and finally figured out what you need. Are you still interested in receiving an answer to this question or have you already found the solution?
Mark Byers
I'm still interested...thanks
MNA
@Mark: Nick's solution doesn't solve my problem because I need each count to have a different name... I need to used them later in an sql report.
MNA
@MNA: Sorry I have changed my answer a number of times. Each time I read your question I interpret it in a new way. In future it would help a lot if you clearly include in your question as many as possible of the following: **Problem description in words**, **Your table structure**, **Example input data (5 - 10 rows per table from your database)**, **The expected result for the example data you gave**, **Your attempt at writing the query**, **Your incorrect result**. Then I think you will get an answer you can use very quickly.
Mark Byers
@MNA: Does my answer work? If not, what is the problem? Are you still looking for an answer to your question?
Mark Byers
A: 

With UNION, you're appending two result sets into a single table. Most SQL implementations will expect the columns from each of the sets being UNIONed together to have the same names. In your case, change the names of INSU_cnt and BANK_cnt to something generic (perhaps 'cnt') and INSURANCE and BANKS to something generic too.

Alternatively, there's UNION CORRESPONDING, which handles different column names by creating separate columns for them, but I don't think that's what you're after.

If this doesn't help, perhaps post the error you're getting from your log.

sasfrog
@sasfrog: Are you sure? I thought MySQL ignored the columns names on the tables after a UNION.
Mark Byers
This isn't true of *most* systems, they expect the same *types* in the columns, and most use the *names* from the first query in the union.
Nick Craver
sasfrog
A: 

This is what it should be

select count(issuer_id) as cnt, min_desc
from issue inner join code on economy_sect = cod_id
where min_desc in ('t', 'b')
group by min_desc
ovais.tariq
A: 

Thank you so much everyone, Mark's solution has worked the best for me. I want to vote his answer as my solution but I can't figure out how :$ I'm new to this site...

MNA