sql server 2008 - Add a line that counts different values - sql-server-2008

Using SQL Server 2008 I get the following output:
I would like to know if there is a way to sum up, in new lines, all the different texts of Col3 to show something like this:

The following is a quick and dirty method, like jayvee suggested. It will only work if the first column of your query is a type you can put a string into. If it not, you may be able to move the summary output to another column.
DECLARE #TestData as TABLE (Col1 nvarchar(50), Col2 nvarchar(50), Col3 nvarchar(50));
Insert Into #TestData
Select 'Whatever1', 'Day1', 'Text1'
UNION ALL Select 'Whatever1', 'Day2', 'Text1'
UNION ALL Select 'Whatever1', 'Day3', 'Text2'
UNION ALL Select 'Whatever2', 'Day1', 'Text1'
UNION ALL Select 'Whatever2', 'Day2', 'Text3'
UNION ALL Select 'Whatever3', 'Day1', 'Text3'
UNION ALL Select 'Whatever3', 'Day2', 'Text2'
UNION ALL Select 'Whatever3', 'Day3', 'Text3';
With OriginalQuery as (
--This should be your original query
Select Col1, Col2, Col3 from #TestData
), GroupData as(
-- This is the summary data you want
Select Col3, COUNT(Col3) as ColCount from OriginalQuery Group By Col3
)
Select * from OriginalQuery --Output the original data
UNION ALL
--This is formatting the group data,
--and adding null columns so it matches the original query length, or the union will fail
Select 'Number of ' + Col3 + ' = ' + Cast(ColCount as nvarchar(10)),
NULL, NULL --One for each column in original query except the first one
From GroupData;

Related

Selecting distinct values from multiple column of a table with their count

i want to to select distinct values from multiple columns of same table with their count
example
and the output should be like this
Since the OP says in his comment that he uses MYSQL this should work
SELECT data,COUNT(data)
FROM
(
SELECT COL1 data
FROM tableso
UNION ALL
SELECT COL2
FROM tableso
UNION ALL
SELECT COL3
FROM tableso
UNION ALL
SELECT COL4
FROM tableso
UNION ALL
SELECT COL6
FROM tableso
UNION ALL
SELECT COL7
FROM tableso
) finaltable group by data;
SQL FIDDLE: http://sqlfiddle.com/#!2/1f8cf/10
I dont think the accepted answer works on MYSQL
UPDATE:
The op has changed his mind about the database(to MSSQL) and the accepted answer has both db versions
Since you are using Sql Server too, will suggest you this way
Use Table valued constructor to convert the columns to rows then count the name
This will avoid multiple table scan's.
SELECT name,
[count]=Count(1)
FROM yourtable
CROSS apply (VALUES (col1),(COL2),(col3),(col4),(COL6),(col7)) cs (name)
GROUP BY name
Note : This will not work in Mysql
SQLFIDDLE DEMO
Get all column values to one row and find the count
SQL SERVER
;WITH CTE AS
(
SELECT COL1 Name
FROM YOURTABLE
UNION ALL
SELECT COL2
FROM YOURTABLE
UNION ALL
SELECT COL3
FROM YOURTABLE
UNION ALL
SELECT COL4
FROM YOURTABLE
UNION ALL
SELECT COL6
FROM YOURTABLE
UNION ALL
SELECT COL7
FROM YOURTABLE
)
SELECT DISTINCT Name,COUNT(Name) OVER(PARTITION BY Name) [COUNT]
FROM CTE
MYSQL
SELECT Name,COUNT(*) [COUNT]
(
SELECT COL1 Name
FROM #TEMP
UNION ALL
SELECT COL2
FROM #TEMP
UNION ALL
SELECT COL3
FROM #TEMP
UNION ALL
SELECT COL4
FROM #TEMP
UNION ALL
SELECT COL6
FROM #TEMP
UNION ALL
SELECT COL7
FROM #TEMP
)TAB
GROUP BY Name

SQLSERVER Select rows as columns even if there is no enough rows

I have a problem to build a query. After searching on stackoverflow i think i need a crosstab. But i don't know what exactly is this. I think it would be quicker if i show you a simplified version of my problem. I would be glad if you could point me to right direction.
This is example of data:
ColumnIDToGroup Value
-----------------------
1 AAAA
1 BBBB
2 AAAA
2 BBBB
2 CCCC
I need to build a query to get the data in this format:
ColumnIDToGroup Value1 Value2 Value3 Value4 Value5
------------------------------------------------------------
1 AAAA BBBB 'Empty' 'Empty' 'Empty'
2 AAAA BBBB CCCC 'Empty' 'Empty'
As a workarround, I could accept this output, if it is simple to build (when a value is not null, it always have the same size)
ColumnIDToGroup ValueConcat
-------------------------------------
1 AAAABBBB************
2 AAAABBBBCCCC********
SAMPLE TABLE
CREATE TABLE #TEMP(ColumnIDToGroup INT,Value VARCHAR(30))
INSERT INTO #TEMP
SELECT 1, 'AAAA'
UNION ALL
SELECT 1, 'BBBB'
UNION ALL
SELECT 2, 'AAAA'
UNION ALL
SELECT 2, 'BBBB'
UNION ALL
SELECT 2, 'CCCC'
Now select the rows from the table, create a column for Value1, Value2 etc and select the extra columns for Value4,Value5 by UNION all and set text to Empty.
SELECT *,
'Value'+CAST(ROW_NUMBER() OVER(PARTITION BY ColumnIDToGroup ORDER BY VALUE)AS VARCHAR(3)) COL
INTO #NEWTABLE
FROM #TEMP
UNION ALL
SELECT 1,'Empty','Value3'
UNION ALL
SELECT 2,'Empty','Value3'
UNION ALL
SELECT 1,'Empty','Value4'
UNION ALL
SELECT 2,'Empty','Value4'
UNION ALL
SELECT 1,'Empty','Value5'
UNION ALL
SELECT 2,'Empty','Value5'
Now get the columns for pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + COL + ']', '[' + COL + ']')
FROM (SELECT DISTINCT COL FROM #NEWTABLE) PV
ORDER BY COL
Now pivot the query
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT * FROM
(
SELECT *
FROM #NEWTABLE
) x
PIVOT
(
MIN(VALUE)
FOR COL IN (' + #cols + ')
) p
ORDER BY ColumnIDToGroup;'
EXEC SP_EXECUTESQL #query
Click here to view the result
If you want in the second specified format, you can use the below query
;WITH CTE AS
(
SELECT *
FROM #TEMP
UNION ALL
SELECT 1,'****'
UNION ALL
SELECT 2,'****'
UNION ALL
SELECT 1,'****'
UNION ALL
SELECT 2,'****'
UNION ALL
SELECT 1,'****'
UNION ALL
SELECT 2,'****'
UNION ALL
SELECT 1,'****'
UNION ALL
SELECT 1,'***'
)
SELECT DISTINCT C2.ColumnIDToGroup,
-- Convert to single row for each ColumnIDToGroup
SUBSTRING(
(SELECT ' ' + CTE.VALUE
FROM CTE
WHERE C2.ColumnIDToGroup=ColumnIDToGroup
ORDER BY
CASE WHEN CTE.VALUE = 'AAAA' THEN 1
WHEN CTE.VALUE = 'BBBB' THEN 2
WHEN CTE.VALUE = 'CCCC' THEN 3
ELSE 4
END
FOR XML PATH('')),2,200000) ValueConcat
FROM CTE C2
Click here to view result

SUM string with comma (SQL Server Reporting Services)

I would like to get string sum check "column 1".
Do you have idea how to do it?
jack, john, bill, joe, sindy
Something similar to
=JOIN(Fields!Column1.Value, ",")
SAMPLE TABLE
CREATE TABLE #TEMP(COLUMN1 VARCHAR(100),COLUMN2 VARCHAR(100))
INSERT INTO #TEMP
SELECT 'jack',1
UNION ALL
SELECT 'john',1
UNION ALL
SELECT 'bill',1
UNION ALL
SELECT 'joe',1
UNION ALL
SELECT 'sindy',1
QUERY
If you need the value with comma separate values and count, you can avoid query before UNION ALL and execute the query only after UNION ALL.
SELECT NULL,COLUMN1,COLUMN2
FROM #TEMP
UNION ALL
SELECT DISTINCT 'TOTAL',
-- Here we convert to comma separated values
SUBSTRING(
(SELECT ', ' + COLUMN1
FROM #TEMP T2
--WHERE C2.Id=Id AND C2.COLUM=COLUM
FOR XML PATH('')),2,200000) COLUMN1,
COUNT(COLUMN1) COLUMN2
FROM #TEMP T1

mysql - Select the 3 smallest values from multiple columns

ID COL1 COL2 COL3 COL4 COL5 COL6 COL7
-------------------------------------
1 4 13 8 0 9 11 2
2 12 3 3 10 17 12 9
3 17 0 0 19 3 1 3
4 5 0 16 0 9 11 2
Here is an example table of data.
What I need to be able to do is to select and label the three smallest values in each row so I can identify each one.
For instance I want to know that in Row2 the three smallest values are 3,3,9 and that they are in COL2,COL3,COL7
I am thinking that I need to incorporate the LEAST() command provided in mysql but it only seems to return one value (the smallest one).
SELECT LEAST(COL1,COL2,COL3,COL4,COL5,COL6,COL7)
I cant seem to figure out how to get the 3 smallest values instead of just one.
Unfortunately your table is not normalized :(
In this case a possible solution is to unpivot the table using a query like this:
CREATE VIEW unpivoted AS
SELECT id, 'col1' colname, col1 as value FROM Table1
UNION ALL
SELECT id, 'col2' colname, col2 FROM Table1
UNION ALL
SELECT id, 'col3' colname, col3 FROM Table1
UNION ALL
SELECT id, 'col4' colname, col4 FROM Table1
UNION ALL
SELECT id, 'col5' colname, col5 FROM Table1
UNION ALL
SELECT id, 'col6' colname, col6 FROM Table1
UNION ALL
SELECT id, 'col7' colname, col7 FROM Table1
and then use a query like the below to find 3 minimum values and then pivot results back:
SET #x = 0;
Set #lastid = -999;
SELECT id,
min( IF( x = 0, colname, null )) As Colname1,
min( IF( x = 0, value, null )) As value1,
min( IF( x = 1, colname, null )) As Colname2,
min( IF( x = 1, value, null )) As value2,
min( IF( x = 2, colname, null )) As Colname3,
min( IF( x = 2, value, null )) As value3
FROM (
SELECT id, colname, value,
IF( #lastid = id, #x:=#x+1,
IF( (#lastid:=id), #x:=0, #x:=0 )
) As x
FROM unpivoted
ORDER BY id, value
) q
WHERE x < 3
GROUP BY id
Demo: http://sqlfiddle.com/#!2/f20ee4/5
But the speed of these queries will be horribly slow, don't even try them on a big table.
You need to normalize the table.
Kordirko's solution is may be the fastest way to do it (without a whole lot of comparison logic on each row). However, the following is more intuitive, in my opinion:
select id,
substring_index(group_concat(colname order by value), ',', 3) as Top3Columns,
substring_index(group_concat(value order by value), ',', 3) as Top3Values
from unpivoted
group by id;
This puts the names and values each in one column, as a concatenated list. You can use a similar idea if you want them in separate columns.

how to get the table column names as entries in result column set?

The database scheme consists:
Table1(code, col1, col2, col3, col4, col5)
What to do is:
For the Table1 with the maximal code value from Table1 table, obtain all its characteristics (except for a code) in two columns:
The name of the characteristic (a name of a corresponding column in the PC table);
Value of the characteristic.
I don't have any idea how to get the table column names in my result column set.
The final result will look like:
chr value
col1 133
col2 80
col3 28
col4 2
col5 50
This is an unpivot operation. The simplest way is using union all. However, the following is generally more efficient:
select (case when n.n = 1 then 'col1'
when n.n = 2 then 'col2'
when n.n = 3 then 'col3'
when n.n = 4 then 'col4'
when n.n = 5 then 'col5'
end) as chr,
(case when n.n = 1 then col1
when n.n = 2 then col2
when n.n = 3 then col3
when n.n = 4 then col4
when n.n = 5 then col5
end) as value
from table t cross join
(select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
) n;
This is more efficient when your table is big or a complicated subquery.
The union all version is:
select 'col1', col1 from table t union all
select 'col2', col2 from table t union all
select 'col3', col3 from table t union all
select 'col4', col4 from table t union all
select 'col5', col5 from table t;
SELECT 'col1', MAX(col1) FROM table1
UNION
SELECT 'col2', MAX(col2) FROM table1
UNION
...
SELECT 'cd' as chr, cd as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
UNION
SELECT 'model' as chr, cast(model as varchar)as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
UNION
SELECT 'speed' as chr,cast(speed as varchar) as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
UNION
SELECT 'ram' as chr, cast(ram as varchar) as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
UNION
SELECT 'hd' as chr, cast(hd as varchar) as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
UNION
SELECT 'price' as chr,cast(price as varchar) as value
FROM pc
WHERE code = (SELECT max(code) FROM pc)
Select char, value
From
(Select code,
cast(speed as varchar(20)) speed,
cast(ram as varchar(20)) ram,
cast(hd as varchar(20)) hd,
cast(model as varchar(20)) model,
cast(cd as varchar(20)) cd,
cast(price as varchar(20)) price
FROM pc
) src
UNPIVOT
(value For char in (speed,ram,hd,model,cd,price)
) As unpvt
where
code in (Select max(code) from PC)`