Include NULL in each "Details Group" in SSRS - sql-server

In SSRS I have a List with, say, a table with two columns: name and number e.g.:
NAME NUMBER
John 123
John 456
John NULL
Name is never null, but number may be. In this case I want the report to include the NULL in each group, like this:
GROUP 1:
John NULL
John 123
GROUP 2:
John NULL
John 456
The SSRS, however, puts the null in a group on its own. How do I accomplish this?

You have told SSRS to group on the NUMBER column, so it will generate a separate group for each value in the NUMBER column and then display those rows. To get what you want, you have to make the data set have the rows you want.
Select Name, Number, cast(Number as varchar(50)) as displayvalue
From mytable
UNION ALL
Select m.Name, m.Number, 'NULL' as displayvalue
From mytable m
Where exists(Select 1 from mytable where Name=m.Name and Number is NULL)
Group by Name, Number
Then group on the Number column but report on the DisplayValue column.

Related

Is there a way to count rows in SQL Server that only count rows with identical information once?

For example let's say this is my data:
PK FNAME LNAME
------------------------
2 Fred SEG
3 Fred SEG
4 Dave Smith
I want to get a result of one Fred and one Dave.
Do you want count(distinct)?
select count(distinct fname)
from t;
If you actually want the rows, with names not repeated, then use:
select t.*
from t
where t.pk = (select min(t2.pk) from t t2 where t2.fname = t.fname);
you just need to add distinct keyword.
select distinct fname, lname from table;
The SQL COUNT function is an aggregate function that returns the number of rows returned by a query. You can use the COUNT function in the SELECT statement to get the number of employees, the number of employees in each department, the number of employees who hold a specific job, etc.
COUNT(*)
The COUNT(*) function returns the number of rows in a table including the rows that contain the NULL values.
Table employees:
Employee_Id
First_Name
Last_Name
Email
Phone_Number
Salary
Department_id
SELECT COUNT(*) FROM employees;

TSQL to choose a record that meets the criteria or first one

I have a table for company phone numbers and one of the columns is IsPrimary which is a boolean type. The table looks like this:
CompanyId | AreaCode | PhoneNumber | IsPrimary
123 212 555-1212 0
234 307 555-1234 1
234 307 555-4321 0
As you can see in the first record, even though the phone number is the only one for CompanyId: 123, it's not marked as the primary.
In such cases, I want my SELECT statement to return the first available number for that company.
My current SELECT statement looks like this which does NOT return a number unless it's set as the primary number.
SELECT *
FROM CompanyPhoneNumbers AS t
WHERE t.IsPrimary = 1
How can I modify this SELECT statement so that it includes the phone number for CompanyId: 123?
The query might be different depending on what you are actually up to.
If you already have the CompanyId and only need the phone number for it, that's easy:
select top (1) pn.*
from dbo.CompanyPhoneNumbers pn
where pn.CompanyId = #CompanyId -- A parameter provided externally, by calling code for instance
order by pn.IsPrimary desc;
However, if you need all companies' data, including one of their phones (for example, you might be going to create a view for this), then you need a correlated subquery:
select c.*, oa.*
from dbo.Companies c
outer apply (
select top (1) pn.*
from dbo.CompanyPhoneNumbers pn
where pn.CompanyId = c.Id
order by pn.IsPrimary desc
) oa;
I have deliberately used outer instead of cross apply, otherwise it will filter out companies with no phone numbers listed.
You can achieve this using an apply statement. This looks at the exact same table and returns the record with the highest IsPrimary so, this would return the records with a 1 in that column. If there are more than one marked as primary or not as primary, then it returns the phone number, with area code, in ascending order.
select b.*
from CompanyPhoneNumbers a
cross apply (
select top 1
*
from CompanyPhoneNumbers b
where b.CompanyId = a.CompanyId
order by b.IsPrimary desc
,b.AreaCode
,b.PhoneNumber
) b

How to skip the max function which has only one entry when i do a group by in SQL Server

I have a requirement where I do a group by the table
Table
Name salary
------------
abc 10000
abc 1000
def 100
Query:
select max(salary)
from table
group by Name
Result:
abc 10000
def 100
I don't want 'def' to be displayed since it's a single entry in the table. How can I achieve this?
You can add a HAVING clause.
Having specifies a search condition for a group or an aggregate.
HAVING can be used only with the SELECT statement. HAVING is typically
used with a GROUP BY clause. When GROUP BY is not used, there is an
implicit single, aggregated group.
select
Name
,max(salary)
from table
group by Name having count(*) > 1
This will only return the aggregates for names that have more than 1 row, which seems to be what you want.
EXAMPLE
declare #table table (name varchar(16), salary int)
insert into #table
values
('abc',10000),
('abc',1000),
('def',100),
('xxf',100)
select
Name
,max(salary)
from #table
group by Name
having count(*) > 1

Pivoting a single field in a table

I have a table of the following structure:
Name
Type
Line
UniqueID
Key
Value
I need to select all the fields except UniqueID field and add a key 'UniqueID' and a Value field with the value of the UniqueID to the result set.
For example if I have three records:
Name Type Line UniqueID Key Value
___________________________________________________________________
John Doe Employee 2 test333 SSN 123-45-2345
John Doe Employee 3 test333 Address 555 Rodeo Drive
Jane Doe Visitor 2 test444 SSN 345-67-8907
my result set would need to be:
Name Type Line Key Value
___________________________________________________
John Doe Employee 2 UniqueID test333
John Doe Employee 2 SSN 123-45-2345
John Doe Emplyee 3 Address 555 Rodeo Drive
Jane Doe Visitor 2 UniqueID test444
Jane Doe Visitor 2 SSN 345-67-8907
Do I use pivots? Can anyone point me into the right direction?
This is kind of an odd request, at least to me. But anyhow, you can approach it a few ways. One way is to use cross apply:
select
name,
type,
line,
newkey,
newvalue
from
table1
cross apply
( values
('UniqueID',uniqueid),
('SSN',Value),
('Address',Value)
) c
(newkey,newvalue)
SQL Fiddle demo
Based on your comments, we'll chuck the union all method.
Here is an incredibly ugly and kludgy unpivot, combined with a union (to get the unique ids):
select
name,
type,
line,
newkey2,
newvalue
from
(select
name,
type,
line,
[key],
[value]
from table1) t1
unpivot
(
newvalue for newkey in ([Value])
) u
unpivot
(newkey2 for newvalue2 in ([key])) u2
union all
select
name,
type,
line,
'UniqueID',
Uniqueid
from
table1
Unpivot SQL Fiddle

UNION with dissimilar columns

TABLE A
ID Name Age
1 John 22
TABLE B
ID Name
5 Erik
I want result like
ID Name Age
1 John 22
5 Erik
When I am performing UNION giving error
"All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists."
How to get desired result?
You could supply a dummy column in lieu of the missing one that returns NULL as below.
SELECT ID,
Name,
Age
FROM TABLE_A
UNION ALL
SELECT ID,
Name,
NULL
FROM TABLE_B

Resources