views:

110

answers:

4
SELECT
  ( SELECT
       SUM(IF(status = 'Active', 1, 0)) AS `univ_active`,
       SUM(IF(status = 'Inactive', 1, 0)) AS 'univ_inactive',
       Count(*)
    FROM online_university
  ) 
 AS tot_university,
( SELECT 
    SUM(IF(status = 'Active', 1,0)) AS `user_active`,
    SUM(IF(status = 'Inactive', 1,0)) AS 'user_inactive'
    Count(*)
  FROM online_register_user)
AS tot_users

Result must be

univ_active=4 univ_inactive=2 tot_university=6
user_active=10 user_inactive=3 tot_users = 13

How can i get this? The above query returning ERROR: Operand should contain 1 column(s)

This to prepare report for a project from all tables returning Active, Inactive, Total records from the table. If this method is wrong then what shall i user? Any suggestion.

+3  A: 

Subqueries can only return one column. You either need to do multiple subqueries, a join, or a cheap concat hack (CONCAT_WS(',', SUM(IF(status = 'Active', 1,0)), SUM(IF(status = 'Inactive', 1,0))) in a single subquery.

BipedalShark
Thank you, It works fine
RSK
+1  A: 

By layout the query as I just did in the question, it becomes very obvious that the alias tot_university, for example would be associated with two columns, which is not possible...

Aside from this syntax/logic error, the whole query seems poorly structured to produce the desired result.

It looks very much like homework, or self assigned learning, so I won't spoil it with a ready-made query, instead here are a few hints.

  • the information comes from two distinct, unrelated tables, maybe use UNION to obtain results in a single query (while effectively running two queries) (you would then use an extra column with some text like 'Univ', 'Public' to differentiate the two lines)
  • the SUM(IF column = x, 1,0) is a good trick to count particular values, without having to do a group by, essentially "rolling up" the counts in one step.
  • the concat() trick is good if your focus is exclusively on textual type results, for example to write, as-is, in a report, otherwise, it would be preferable to keep the results in separate columns, for further processing, display in tables etc...
mjv
yes i did wrong in my query, thank you for your explanation
RSK
+1  A: 

As BipedalShark said, your queries should have 1 column and they have 2 now. But besides that you should think of using count(*) and where clause. So it should be smth like this:

select
 (select count(*) from online_university where status = 'Active') as univ_active,
 (select count(*) from online_university where status = 'Inactive') as univ_inactive,
 (select count(*) from online_register_user where status = 'Active') as user_active,
 (select count(*) from online_register_user where status = 'Active') as user_inactive
Vitaly
good idea, I have one doubt? Will it take too time to execute?
RSK
It won't take much. Count() works very fast, esp. if you have indices on status fields.
Vitaly
+2  A: 

As the error says, you're SELECTing a subquery that returns two columns.

SELECT (one_thing, another_thing) AS combined_thing

doesn't exist in SQL. You would have to put each subquery on its own:

SELECT (
    SELECT SUM(IF(status='Active', 1, 0)) FROM online_university
) AS univ_active, (
    SELECT SUM(IF(status='Inactive', 1, 0)) FROM online_university
) AS univ_inactive, (
    SELECT SUM(IF(status='Active' OR status='Inactive', 1, 0)) FROM online_university
) AS tot_university, (
    SELECT SUM(IF(status='Active', 1, 0)) FROM online_register_user
) AS user_active, (
    -- and so on

However, there is really no benefit to doing all this in a single query. Much easier to say:

SELECT COUNT(*) FROM online_university WHERE status='Active';  -- univ_active
SELECT COUNT(*) FROM online_university WHERE status='Inactive';  -- univ_inactive
SELECT COUNT(*) FROM online_university;  -- tot_university
SELECT COUNT(*) FROM online_register_user WHERE status='Active';  -- user_active
    -- and so on

then present those results together in the application layer. A WHERE clause is faster and can use proper indexes which a calculated expression like SUM/IF cannot.

Simpler still:

SELECT status, COUNT(*) FROM online_university GROUP BY status;
SELECT status, COUNT(*) FROM online_register_user GROUP BY status;
bobince