Aggregate function COUNT not scalar - sql

The COUNT function doesn't result in a scalar as expected:
CREATE TABLE MyTable (Col1 INT, Col2 INT, Col3 INT)
INSERT INTO MyTable VALUES(2,3,9) -- Row 1
INSERT INTO MyTable VALUES(1,5,7) -- Row 2
INSERT INTO MyTable VALUES(2,3,9) -- Row 3
INSERT INTO MyTable VALUES(3,4,9) -- Row 4
SELECT COUNT(*) AS Result
FROM MyTable
WHERE Col3=9
GROUP BY Col1, Col2
I filter out the 3 rows where Col3=9.
In the remaining 3 rows there are two groups:
Group 1 where Col1=2 AND Col2=3 (Row 1 and 3)
Group 2 where Col1=3 AND Col2=4 (Row 4)
Finally I count those two rows.
Therefore, I expect the answer to be a scalar Result = 2 (the two groups where Col3=9).
But I got a non scalar result.
There are other ways to solve the this, so thats not the problem, but where am I thinking wrong?

Seems like you are looking for the total count of all the groups matching any condition. For this try like the following query.
SELECT COUNT(*) [Count] FROM
(
SELECT COUNT(*) AS Result
FROM MyTable
WHERE Col3=9
GROUP BY Col1, Col2
)T
SQL Fiddle

You can use subquery with singe aggregation :
select count(*)
from (select distinct col1, col2
from mytable
where col3 = 9
) t;

Related

SQL query to remove duplicates from a table with 139 columns and load all columns to another table

I need to remove the duplicates from a table with 139 columns based on 2 columns and load the unique rows with 139 columns into another table.
eg :
col1 col2 col3 .....col139
a b .............
b c .............
a b .............
o/p:
col1 col2 col3 .....col139
a b .............
b c .............
need a SQL query for DB2?
If the "other table" does not exist yet you can create it like this
CREATE TABLE othertable LIKE originaltable
And the insert the requested row with this statement:
INSERT INTO othertable
SELECT col1,...,coln
FROM (SELECT
t.*,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col1) AS num
FROM t) t
WHERE num = 1
There are numerous tools out there that generate queries and column lists - so if you do not want to write it by hand you could generate it with these tools or use another SQL statement to select it from the Db2 catalog table (syscat.columns).
You might be better just deleting the duplicates in place. This can be done without specifying a column list.
DELETE FROM
( SELECT
ROW_NUMBER() OVER (PARTITION BY col1, col2) AS DUP
FROM t
)
WHERE
DUP > 1
You can use row_number():
select t.*
from (select t.*,
row_number() over (partition by a, b order by a) as seqnum
from t
) t;
If you don't want seqnum in the result set, though, you need to list out all the columns.
To find duplicate values in col1 or any column, you can run the following query:
SELECT col1 FROM your_table GROUP BY col1 HAVING COUNT(*) > 1;
And if you want to delete those duplicate rows using the value of col1, you can run the following query:
DELETE FROM your_table WHERE col1 IN (SELECT col1 FROM your_table GROUP BY col1 HAVING COUNT(*) > 1);
You can use the same approach to delete duplicate rows from the table using col2 values.

Count to begin at 1

I want to value a column with a count. I am looking through the table to find the next count number. If a row does not exists I would like to begin the count with 1 rather than 0. Can someone assist me with my below query. If a row does exist then I would like to simply take the column 3 and add 1 to the next sequence number.
SELECT
COl1,
Col2,
CAST((MAX(col3) + 1) AS SMALLINT) AS col3
FROM table1
GROUP BY col1, col2
You are using a MAX() function that returns the highest value. If you want to count the number of occurences (rows), you need to use the COUNT() function.
Edit
More details would be needed, but in SQL Server you could try something like this:
SELECT col1, col2, count(1) + 1 as col3
FROM table1
GROUP BY col1, col2
It would count the number of distinct pair of col1 and col2, then add one to it and display it as col3. From what I understand, you do not really need to use the current value of col3, since you are recalculating it.
If you want all combinaison with 1 if one combinaison dont exist try this:
with combinaison as (
select distinct f1.col1, f2.col2
from table1 f1 cross join table1 f2
)
SELECT f1.col1, f1.col2, ifnull(MAX(f1.col3), 0) + 1 AS col3
FROM table1 f1
GROUP BY f1.col1, f1.col2
union all
select f2.col1, f2.col2, 1 AS col3
from combinaison f2 left outer join table1 f3 on (f2.col1, f2.col2)=(f3.col1, f3.col2)
where f3.col1 is null

DB2, SQL query to SUM 2 columns

I need to add to columns in a row.
Table Data
id
Col1
Col2
1
10
20
2
11
20
3
12
20
Result expected
id
Sum
1
30
2
31
3
32
I tried sum(col1 + col2), but that gives the sum of all the columns together.
sum() is a aggregating function (one that give a single result for a group of rows), not a algebraic one: You want the addition (the mathematical sum) of the two columns:
select id, col1 + col2 as sum
from mytable
we have two type of columns in group clause (Aggregation column and Group column) in this query
select id, col1 + col2 as sum
from mytable
group by id
we have to insert id, col1 and col2 in front of group by, otherwise we get this error
Column 'TEST.COL1' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
if use MAX() aggregation function like this
SELECT
ID,
MAX(COL1+COL2) AS SUM
FROM TEST
GROUP BY ID
we get the result BUT this isn't good idea because the cost of this code 4 times more than
bellow code
SELECT
ID,COL1+COL2 AS SUM
FROM TEST
Try this
select id, col1 + col2 as sum
from mytable
group by id

sqlite: select all columns where one filed has max value over all columns

I have a table like this:
id int, col1 int, ...
Different rows can have col1 of same value.
Now I want to gather all rows where col1 has a the maximum value.
e.g. this table values
1 4
2 3
3 4
The query shall give my row 1 and 3
You can use subquery:
SELECT id, col1
FROM tab
WHERE col1 = (SELECT MAX(col1) FROM tab);
SqlFiddleDemo

Select 1 Col_Name means in sql server 2008?

Today i found a query like
SELECT 1 [Col_name] FROM MyTable
and
SELECT [Col_name] FROM MyTable
Both seems to return the same result. I am confused.
This is the actual query:
SELECT 1 Col1 FROM [Table1] WHERE Col1 = 1
UNION
SELECT 2 Col1 FROM [Table1]
Any help is appreciated
Your query:
SELECT 1 [Col_name] FROM MyTable
will return the literal value 1 with an alias col_name. Even if col_name is an identifier in your table.
However:
SELECT [Col_name] FROM MyTable;
will select col_name from your table.
The same with:
SELECT 1 Col1 FROM [Table1] WHERE Col1 = 1
UNION
SELECT 2 Col1 FROM [Table1]
Will give you only two rows:
1
2
regardless the values in the table. Because SELECT 1 Col1 FROM [Table1] WHERE Col1 = 1 returns the literal value 1 with an alias col1, SELECT 2 Col1 FROM [Table1] returns the literal value 2 with the same alias col1 with UNION(Distinct select) set operator, will give you only two values (1, 2) since they are the only distinct values.
Live Demo
on the actual query, Col1 are called the alias for the column which has the value of 1.
if Col1 is not specified, the column with value given of 1 has no columnName.
SQLFiddle Demo (for more clarification)