Count to begin at 1 - sql

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

Related

Aggregate function COUNT not scalar

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;

SQL DISTINCT based on a single column, but keep all columns as output

--mytable
col1 col2 col3
1 A red
2 A green
3 B purple
4 C blue
Let's call the table above mytable. I want to select only distinct values from col2:
SELECT DISTINCT
col2
FROM
mytable
When I do this the output looks like this, which is expected:
col2
A
B
C
but how do I perform the same type of query, yet keep all columns? The output would look like below. In essence I'm going through mytable looking at col2, and when there's multiple occurrences of col2 I'm only keeping the first row.
col1 col2 col3
1 A red
3 B purple
4 C blue
Do SQL functions (eg DISTINCT) have arguments I could set? I could imagine it to be something like KeepAllColumns = TRUE for this DISTINCT function? Or do I need to perform JOINs to get what I want?
You can use window functions, particularly row_number():
select t.*
from (select t.*, row_number() over (partition by col2 order by col2) as seqnum
from mytable t
) t
where seqnum = 1;
row_number() enumerates the rows, starting with "1". You can control whether you get the oldest, earliest, biggest, smallest . . .
You can use the QUALIFY clause in Teradata:
SELECT col1, col2, col3
FROM mytable
QUALIFY ROW_NUMBER() OVER(PARTITION BY col2 ORDER BY col2) = 1 -- Get 1st row per group
If you want to change the ordering for how to determine which col2 row to get, just change the expression in the ORDER BY.
With NOT EXISTS:
select m.* from mytable m
where not exists (
select 1 from mytable
where col2 = m.col2 and col1 < m.col1
)
This code will return the rows for which there is not another row with the same col2 and a smaller value in col1.

Sql find duplicates in filed two IF field one is unique

Trying to wrap my head around this but its just spinning in circles...
I have a sql right now and get to a point where I have values as such:
select T1.col1, T2.col2
from T2, T1
where T2.recNo = T1.recNo
AND T2.id=3
AND T1.recNo IN(
select recNo from T1 where col1 IN (
select col1 from T1 group by col1 having COUNT(*) >2))
col1|col2
111|123
111|123
222|456
222|456
222|456
333|789
333|700
etc...
This is a pretty large output and what I am trying to find is if there are any values in col2 that are NOT the same for each grouping of values in col1 (i know for certain col1 is unique) I dumped the output to a file and will try to figure it out in perl next.
The output i am trying to get is:
col1|col2
333|789
333|700
You can do this with aggregation:
select col1
from (<your query here>) s
group by col1
having min(col2) <> max(col2);
This will return all col1 values that have more than one col2 value.

select all columns with one column has different value

In my table,some records have all column values are the same, except one. I need write a query to get those records. what's the best way to do it? the table is like this:
colA colB colC
a b c
a b d
a b e
What's the best way to get all records with all the columns? Thanks for everyone's help.
Assuming you know that column3 will always be different, to get the rows that have more than one value:
SELECT Col1, Col2
FROM Table t
GROUP BY Col1, Col2
HAVING COUNT(distinct col3) > 1
If you need all the values in the three columns, then you can join this back to the original table:
SELECT t.*
FROM table t join
(SELECT Col1, Col2
FROM Table t
GROUP BY Col1, Col2
HAVING COUNT(distinct col3) > 1
) cols
on t.col1 = cols.col1 and t.col2 = cols.col2
Just select those rows that have the different values:
SELECT col1, col2
FROM myTable
WHERE colWanted != knownValue
If this is not what you are looking for, please post examples of the data in the table and the wanted output.
How about something like
SELECT Col1, Col2
FROM Table
GROUP BY Col1, Col2
HAVING COUNT(*) = 1
This will give you Col1, Col2 that have unique data.
Assuming col3 has the difs
SELECT Col1, Col2
FROM Table
GROUP BY Col1, Col2
HAVING COUNT(*) > 1
OR TO SHOW ALL 3 COLS
SELECT Col1, Col2, Col3
FROM Table1
GROUP BY Col1, Col2, Col3
HAVING COUNT(Col3) > 1

Inserting multiple select statements into a table as values

Is it possible to do something like this in SQL Server:
INSERT INTO MyTable (Col1,Col2,Col3,Col4,Col5,Col6,Col7) VALUES
SELECT Col1 FROM Func1(),
SELECT Col2 FROM Func2(),
SELECT Col3,Col4,Col5 FROM Func3(),
SELECT Col6 FROM Func4(),
SELECT Col7 FROM Func5()
I have a large number of functions which return one-value results and one function which returns 3 columns. I would like to insert all of this data into one row of a table?
I can see the function returning muliple columns as possibly being a problem?
If all functions return just one row...
INSERT INTO
MyTable (Col1,Col2,Col3,Col4,Col5,Col6,Col7)
SELECT
f1.col1, f2.col2, f3.col3, f3.col4, f3.col5, f4.col6, f5.col7
FROM
(SELECT Col1 FROM Func1()) AS f1
CROSS JOIN
(SELECT Col2 FROM Func2()) AS f2
CROSS JOIN
(SELECT Col3,Col4,Col5 FROM Func3()) AS f3
CROSS JOIN
(SELECT Col6 FROM Func4()) AS f4
CROSS JOIN
(SELECT Col7 FROM Func5()) AS f5
If the functions return more than one row, you need to join them in the normal way; with predicates that determine which left row gets joined to which right row.
INSERT INTO MyTable (Col1,Col2,Col3,Col4,Col5,Col6,Col7) VALUES
SELECT Col1 FROM Func1(),
SELECT Col2 FROM Func2(),
SELECT Col3 FROM (SELECT Col3,Col4,Col5 FROM Func3()),
SELECT Col4 FROM (SELECT Col3,Col4,Col5 FROM Func3()),
SELECT Col5 FROM (SELECT Col3,Col4,Col5 FROM Func3())
SELECT Col6 FROM Func4(),
SELECT Col7 FROM Func5()
You have to remove Values and all ","and brackets around each select statement.