I have a table called product and its data as follows,
| ProductID | ProductName | Code | SortValue |
+-----------+-------------+------+-----------+
| 10 | AAA | 13RT | 1 |
| 11 | BBB | 14RT | 2 |
| 12 | CCC | 15RT | 3 |
| 13 | DDD | 16RT | 4 |
| 14 | EEE | 17RT | 5 |
| 15 | FFF | 19RT | 6 |
I wrote a merge query to insert product data as follows,
MERGE [product] AS target
USING (SELECT #productName, #code) AS source (productname, code)
ON (target.code = source.code)
WHEN matched THEN
UPDATE
SET productname = source.productname,
code = source.code,
WHEN NOT matched THEN
INSERT (productname, code, sortvalue)
VALUES (source.productname, source.code, 1)
OUTPUT inserted.productid INTO #insertedTable;
You can see the product table has a column SortValue and each product has a sort value. I need to insert newly inserting product sort value as 1 and need to update the existing product's sort value by one. To do that, I wrote the following query.
UPDATE product
SET SortValue = sortvalue + 1
WHERE sortvalue >= 1;
I need to execute the above query before inserting new records. How can I do it, I apply it after the merge statement's NOT matched part, but it makes an error. How can I sort this issue?
What I'm trying to do
In my report, I am trying to get some basic data in a tablix. In this tablix there is one main summary row and detail rows inside it. What I want to do is put the details in the child row but split into three columns.
For example my tablix looks like this right now
Row11| Row12| Row13 |
1 | 5 | 4 |
| Column1 | Column2|
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |
2 | 20 | 25 |
Column1 Column2 |
| 7 | 8 |
| 9 | 5 |
| 3 | 6 |
(This is just a demo table. The number of columns in my application is not necessarily this number and it should be irrelevant anyway)
How I want it to look like:
Row11| Row12| Row13 |
1 | 5 | 4 |
| Column1 | Column2| Column1 | Column2| Column1 | Column2|
| 1 | 4 | 2 | 5 | 3 | 6 |
2 | 20 | 25 |
| Column1 | Column2| Column1 | Column2| Column1 | Column2|
| 7 | 8 | 9 | 5 | 3 | 6 |
I just want to split the detail table into three columns. I have tried various approaches but in vein.
What approaches have I tried?
Attaching a sub report method. I attached a sub report and divided the report into three separate tables and split the columns in this order. This works except that it is terribly slow when trying to get large amount of data. Really do not want to do this.
The method mentioned here. Did not work.
I have been experimenting with the SQL itself as well but SQL does not look like to be an issue here.
Tried with Matrix instead of tablix too trying to push my limits but did not succeed.
Side note: If it matters I am using SSRS SDK for PHP and grabbing the PDFs from the Report Server and using Visual Studio to design the reports.
This seems such a simple thing but I am stuck with this. Has anybody in a situation like this before?
Please let me know if you need more clarifications.
Create three detail tables, adjust which rows get shown in each, and put them in a List.
This solution works on the assumption that your raw data looks something like this:
Add a table report item and add the Column1 and Column2 data to it, leaving the grouping as just the details. Right-click the detail row, and go to Row Visibility.
Switch this to 'Show or hide based on an expression', and add this expression:
=IIF(RowNumber("tblFirstColumn") MOD 3 = 1, False, True)
This will make only the first, fourth, seventh etc. record show in that table. Paste two copies of this table next to the first, and adjust the row visibility expression on each:
=IIF(RowNumber("tblSecondColumn") MOD 3 = 2, False, True)
=IIF(RowNumber("tblThirdColumn") MOD 3 = 0, False, True)
Next add a List item. Change the row grouping of the list to group by Row11, add each row field to the top of this list (as text boxes or a non-grouped table), and move the three detail tables into the bottom of the list.
This should perform better than using subreports. I understand that when using subreports the datasets will be queried with every instance of that subreport. With all the design in one report, the queries should only run once.
Method 1: main tablix = three columns with TWO detail rows. In the 2nd detail row merge the three columns together. Create a new tablix for the detail information and put it inside the merged detail cell.
Method 2: main tablix = six columns and two detail rows. In the 1st detail row merge cells 1/2, 3/4, and 5/6 together.
I had to tackle a same problem once and the way I did it is by "Inserting a TABLIX inside a TABLIX". I believe if you follow the link below that shuold resolve what you are looking for:
http://www.sqlcircuit.com/2012/03/ssrs-how-to-show-tablix-inside-tablix.html
Waht I have additionaly done in my report to increase the width of the nested tablix so that it does not affect the width on the main tablix is:
1) On the the row above the insertted tablix I have created a column and kept it empty and merged the cell below it where the nested tablix should be.
2) now you can increase the size of the empty column (make the borders invisible) to what ever the width of the inserted TABLIX you would like.
Hope this helped.
For what it's worth (I see you have already accepted an answer), I think this could be done primarily within SQL if you wished.
Assuming your raw data looks like this:
/-------------------------------------------\
| Row11 | Row12 | Row13 | Column1 | Column2 |
|-------+-------+-------+---------+---------|
| 1 | 5 | 4 | 1 | 4 |
| 1 | 5 | 4 | 2 | 5 |
| 1 | 5 | 4 | 3 | 6 |
| 2 | 20 | 25 | 3 | 6 |
| 2 | 20 | 25 | 7 | 8 |
| 2 | 20 | 25 | 9 | 5 |
\-------------------------------------------/
Let's create demo data to illustrate:
CREATE TABLE data (
Row11 INT,
Row12 INT,
Row13 INT,
Column1 INT,
Column2 INT
)
INSERT INTO data
SELECT 1,5,4,1,4
UNION
SELECT 1,5,4,2,5
UNION
SELECT 1,5,4,3,6
UNION
SELECT 2,20,25,7,8
UNION
SELECT 2,20,25,9,5
UNION
SELECT 2,20,25,3,6
You could aggregate each summary and detail row like this:
SELECT DISTINCT d.Row11,
d.Row12,
d.Row13,
dfirst.Column1,
dfirst.Column2,
dsecond.Column1,
dsecond.Column2,
dthird.Column1,
dthird.Column2
FROM data d
CROSS APPLY
(
SELECT TOP 1 Column1, Column2
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
ORDER BY 1,2
) dfirst
CROSS APPLY
(
SELECT Column1, Column2
FROM
(
SELECT Column1, Column2, ROW_NUMBER() OVER (ORDER BY Column1, Column2) AS rownumber
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
) drows
WHERE rownumber = 2
) dsecond
CROSS APPLY
(
SELECT TOP 1 Column1, Column2
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
ORDER BY 1 DESC,2 DESC
) dthird
Which gives the results:
/-----------------------------------------------------------------------------------\
| Row11 | Row12 | Row13 | Column1 | Column2 | Column1 | Column2 | Column1 | Column2 |
|-------+-------+-------+---------+---------+---------+---------+---------+---------|
| 1 | 5 | 4 | 1 | 4 | 2 | 5 | 3 | 6 |
| 2 | 20 | 25 | 3 | 6 | 7 | 8 | 9 | 5 |
\-----------------------------------------------------------------------------------/
It should then be relatively trivial to group this in the table in your SSRS report by Row11, Row12, Row13, placing the values for Row11, Row12 and Row13 into the Group Header row and the values for all 6 Column1 and Column2 values into the detail row:
Design:
Results:
Note: this only works for 3 (or fewer) pairs of Column1/Column2 values per tuple of Row11, Row12, Row13 values.
I have 3 tables. ID and Name is the primary key for the first table.
First Table
ID | Name | Date
----------------
1 | AA | 11/02
2 | BB | 04/10
ID, Name and Option are the primary key for second table:
Second Table
ID | Name | Option | SeqNo
---------------------------
3 | DD | LOVE | 1
4 | EE | SINGLE | 1
Option is the primary key for the third table:
Third Table
Option | Status
---------------
LOVE | Y
MARRIED| Y
SINGLE | N
After I join these tables, I will get like this.
ID | Name | Option | SeqNo | Status
------------------------------------
1 | AA | NULL | NULL | NULL
2 | BB | NULL | NULL | NULL
3 | CC | LOVE | 1 | Y
4 | DD | SINGLE | 1 | N
My question is, how to change the NULL value to a value contain in another table?
As an example, The Option column must be filled in with the value inside the third table. I'm using SQL Server 2005
This link describes how to replace null values in different sql engines, including sql server -
http://www.sqlines.com/oracle/functions/nvl
Basically, the syntax you are looking for is -
ISNULL(SeqNo, 'N/A')
Hi I have doubt in sql server
Trantable:
empid | deptid | Projectname | Transactionid
1 |10 | test | 1
2 |11 | test1 | 2
2 |10 | jai | 3
2nd table: dimemp ....> here dimemp is scdtype2 dimension.its all ready done
empkey | empid | ename | flag
1 | 1 | a | 1
2 | 2 | b | 1
3 | -1 | na | 1
3rd table: dimdept------>here dimdept is scdtype2 dimension.implementaion allready done.
deptkey | deptid | deptname | flag
1 | 10 | hr | 1
2 | 11 | ceo | 1
3 | -1 | NA | 1
Here I want load trantable data into facttran table with corresponding keys. here transactionid is unique column
to identiy unique record.
Facttran table structure look like below and factran we need to maintain scd type1 data.
empkey | deptkey | projectname |transactionid
I tried like below query
merge into facttran target
using (select ISNULL(a.empkey, (select empkey from Dimemp where empid = -1)) empkey,ISNULL(b.deptkey, (select deptkey from dimdept where deptid = -1)) deptkey, c.projectname, c.transactionid
from trantable c
left join dimemp a on a.empid=c.empid and a.flag=1
left join dimdept b on b.deptid=c.deptid and b.flag=1)source
on target.transactionid=source.transactionid
when not matched
then insert ([deptkey],[empkey],[projectname],[transactionid])
values(source.deptkey,source.empkey,source.projectname,source.transactionid)
when matched
then update set target.empkey=source.empkey ,
target.deptkey=source.deptkey,
target.projectname=source.projectname,
target.transactionid=source.transactionid ;
then I got output like below
Table :facttran
empkey | deptkey | projectname |transactionid
1 | 1 | test | 1
2 | 2 | test1 | 2
2 | 1 | Jai | 3
upto now its working fine.
2nd day in my trantable few records updated and few records insert in sourc trantable.based on below table data I want update in facttable with corresponding key.
2nd table: dimemp ....> here dimemp is scdtype2 dimension
empkey | empid | ename | flag
1 | 10 | a | 0
2 | 11 | b | 1
3 | -1 | na | 1
4 | 10 | aaa | 1
3rd table: dimdept------>here dimdept is scdtype2 dimension.implementaion allready done.
deptkey | deptid | deptname | flag
1 | 10 | hr | 0
2 | 20 | ceo | 1
3 | -1 | NA | 1
4 | 10 |hrdept | 1
Trantable:
empid | deptid | Projectname | Transactionid
1 |11 | test | 1 ------record updated in source side here deptid changed from 10 to 11
1 |11 | test123 | 2 -------Here empid changed from empid 2 to 1 and projectname changed test1 to test123
2 |10 | jai | 3 ------here no records are not changed
1 |10 | cod | 4 ----------new rocrd is came
based on above trantable.I want facttran table data look like below.
Table :facttran
empkey | deptkey | projectname |transactionid
1 | 2 | test | 1
1 | 2 | test123 | 2
2 | 1 | Jai | 3
4 | 10 | cod | 4
when I ran 2nd time with same query.I am not able get to expected result.
here mainily source trantable related transactioni id is exist or not in facttran table .if not exist then we need to insert correspondig dimensionkeys with lates flaf=1
values.if we found transactionid exist in fact table then we need to updated existing dimension corresonding key.
suppose if we take transactionid=1 records here only chnaged deptid not empid that time we donot need update empid corresponding lates flag=1 corresondingkey
we need check exisig transaction id is updated each dimension need to check exist or not if not exist latest flag=1 related corresponding key.
if exist we donot need to updated that one.if new reocrds came then we need to insert with latest flag=1 corresponding keys in factran table.
please tell me how to write query to achive this task in sql server.
Running SQL Server 2012, I have a table in the following format:
ENC_ID | Name | ED_YN | Seq
-------------------------------------
1234 | John | Y | 1
1234 | Sally | N | 2
2345 | Chris | N | 1
2345 | Sally | N | 2
I would like to unpivot this into a entity-attribute-value list (if that's the right terminology - I am thinking of them as key-value pairs grouped by IDs), with the following format:
ENC_ID | Seq | Key | Value
--------------------------------------
1234 | 1 | Name | John
1234 | 1 | ED_YN | Y
1234 | 2 | Name | Sally
1234 | 2 | ED_YN | N
2345 | 1 | Name | Chris
2345 | 1 | ED_YN | N
2345 | 2 | Name | Sally
2345 | 2 | ED_YN | N
I have seen various answers to this using UNION or UNPIVOT, but these solutions tend to be long and must be closely customized to the table. I'm looking for a solution that can be reused without a great deal of rewriting as this pattern solves a problem I expect to run into frequently (ingesting data from star-schema into Tableau via extracts, where I don't necessarily know the number of value columns).
The closest thing I've found to solve this is this question/answer but I haven't had success altering the solution to add ENC_ID and Seq to each row in the result table.
Thanks.
I will use Cross Apply with table valued Constructor to do this unpivoting
select ENC_ID, Seq, Key, Value
from yourtable
cross apply
(values ('Name',Name),
('ED_YN',ED_YN)) CS (Key,Value)
You can try below query. This uses classic UNPIVOT syntax.
Since I am unsure about your column types I have casted both of them as varchar(100). You can increase length from 100.
Working sql fiddle demo link :
select enc_id,seq, k [key],v [value] from
(select enc_id,seq,cast(name as varchar(100)) as name, cast(ed_yn as varchar(100)) as ed_yn from r)s
UNPIVOT
( v for k in ([name],[ed_yn])
)up