I've searched StackOverflow and google for quite some time now and haven't been able to find an answer even remotely close to my desired solution using SQL. I have a CSV file (1 table) and it has data for numerous users. The problem is each user has multiple rows with multiple scores but same UserID. I would like to move those scores into their own column to present one row with all of the user's data. How can I achieve this using SQL?
Example of Current Layout:
UserID FNm LNm Measure Score
0001 person one LNF 26
0001 person one NFS 74
0001 person one CFS 54
0002 person two LNF 35
0002 person two NFS 43
0002 person two CFS 33
Desired solution:
UserID FNm LNm LNF NFS CFS
0001 person one 26 74 54
0002 person two 35 43 33
First, insert all records as is into some temporary table.
Second, insert combined data into needed table; select part is about:
select UserID, FNm, LNm,
max(case when Measure='LNF' then Score else 0 end) as LNF,
max(case when Measure='NFS' then Score else 0 end) as NFS,
max(case when Measure='CFS' then Score else 0 end) as CFS
from temptable
group by UserID, FNm, LNm
First you need to load your excel spreadsheet to SQL Server.
I suggest using SSIS, here is an article to help you:
http://www.techrepublic.com/blog/datacenter/how-to-import-an-excel-file-into-sql-server-2005-using-integration-services/205
then you can use #Arvo's approach to sum the values
Related
I have two tables in SQL Server, Portfolio and Master. The portfolio holds inventory, while the master table defines the room types and number of bedrooms.
select
PropertyNumber,
Unit,
Rent,
Code
from Portfolio
The above query returns the following records:
01
111
500
2BD
01
112
200
1BD
While the below query returns the following:
select
Property,
Unit,
Duplex
from [Master]
01
1BD
1
01
2BD
2
01
3BD
3
I'm trying to split rows based on the Duplex column in my Master table. For example, in the initial output, I'd like to split that first record into two rows based on the 2BD data (and also divide the Rent column by that number). In other words, the final result would look like this:
01
111
250
2BD
01
111
250
2BD
01
112
200
1BD
I won't write your query for you, but I'll tell you how to do it, if I understand the question.
IIUC you want to produce N rows for master based on duplex.
To produce N rows, create a little table, perhaps like this:
select distinct duplex as n into #N
then
select m.* from master as m join #N
on duplex <= n
The rest is easy: extend the join to portfolio, and divide rent by duplex.
I am trying to take daily data (not every day has data) and sum it by weeks starting on monday. Below is a very small sample for the Data I have. the code is irrelvant for the summing purposes needed here.
Data have:
ID
PKG
Revdt
code
QTY
70
17AB
02AUG2021:00:00:00
01
7
70
17AB
04AUG2021:00:00:00
02
-10
70
17AB
05AUG2021:00:00:00
01
8
70
17AB
10AUG2021:00:00:00
01
7
70
17AB
1QAUG2021:00:00:00
01
7
73
12AC
02AUG2021:00:00:00
09
0
73
17AC
07AUG2021:00:00:00
01
7
Data want
ID
PKG
Revdt
code
QTY
70
17AB
02AUG2021:00:00:00
01
5
70
17AB
09AUG2021:00:00:00
01
14
73
12AC
02AUG2021:00:00:00
01
7
I have tried the below
Proc sql;
connect to odbc (dsn='' id='' p='');
create table work.WeeklySum as select distinct * from connection to odbc
(select ID, Pkg, datepart(week, revdt), code, sum(qty)
from datebase
group by datepart(week, revdt) );
disconnect from odbc;
quit;
However when i run it, it says "error:proc sql requires any created table to have atleast 1 column"
I would just pull the data with the daily rows first into SAS. If it is too big, write a macro to run it in loops with small chunks.
Once you get the daily dataset into SAS, create a separate table with weekly datetimes (here I am creating a table begins with Jan 1, 2021 and has a row for every week from there - change the inputs according to your need):
data weeks;
format week_date datetime19.;
do i = 0 to 52;
week_date = intnx('dtday', "01jan2021:00:00:00"dt, 7*i,'s');
output;
end;
drop i;
run;
Once you have this weeks dataset, left join your daily dataset to it using:
week_date <= revdt < intnx('dtday', week_date, 7, 's')
and then sum your variable by week_date.
select ID, Pkg, datepart(week, revdt), code, sum(qty)
from datebase
group by datepart(week, revdt)
This is not valid in SQL Server, so this will be your problem. SAS lets you do this, but when you do pass-through SQL, you have to follow their rules. In the case of SQL Server, every variable that is not part of a summary function (here, sum(qty) is the only summary function call) has to be part of the group by.
If you want to group by inside SQL Server, you'll have to modify your query to be a join from the (ID,Pkg) query to the (datepart,sum) query. SAS does this for you, but SQL Server won't.
The situation is quite complicated to express in the title. An example should be much easier to understand.
My table A:
uid id ticket created_date
001 1 movie 2015-01-23 08:23:16
002 25 TV 2012-01-13 12:02:20
003 1 movie 2015-02-01 07:15:36
004 1 movie 2014-02-15 15:38:40
What I need to achieve is to remove duplicate records that appear within 31 days between each other and retain the record that appear first. So the above table would be reduced to B:
uid id ticket created_date
001 1 movie 2015-01-23 08:23:16
002 25 TV 2012-01-13 12:02:20
004 1 movie 2014-02-15 15:38:40
because the 3rd row in A were within 31 days of row 1 and it appeared later than row 1 (2015-02-01 vs 2015-01-23), so it gets removed.
Is there a clean way to do this?
I would suggest the following approach:
SELECT A.uid AS uid
INTO #tempA
FROM A
LEFT JOIN A AS B
ON A.id=B.id AND A.ticket=B.ticket
WHERE DATEDIFF(SECOND,B.date,A.date) > 0 AND
DATEDIFF(SECOND,B.date,A.date) < 31*24*60*60;
DELETE FROM A WHERE uid IN (SELECT uid FROM #tempA);
This is assuming that by 'duplicate records' you mean records that have both identical id as well as identical ticket fields. If that's not the case you should adjust the ON clause accordingly.
I am using Crystal report to do a sum over 3 columns. The table structure looks like:
table #test (Country VARCHAR(10), Name VARCHAR(10), Weight VARCHAR(10), Qty INT)
I wrote a query in the crystal command pane when I do the connection:
SELECT Country, SUM(Qty) As Qty, Name, Weight FROM #test GROUP BY Country, Name, Weight
I should get something like:
CANADA 2 John 200
US 1 John 160
US 2 Mike 180
US 6 Sam 90
However, the crystal report does not sum the field, instead it pulls every single row, and the result looks like I write the query:
SELECT Country, Qty, Name, Weight FROM #test
CANADA 1 John 200
CANADA 1 John 200
US 1 John 160
US 2 Mike 180
US 3 Sam 90
US 3 Sam 90
By the way, the backend database is called "Cache". It might be due to there are some hidden characters, but I cannot see them. I have used replace (char(10)), replace (char(13) and trim to try to clean.
I also try to pull the table column directly without writing the query, but I do not know how to sum three columns (Country, Name and Weight). I only know how to sum one column. By the way, the request do not want the details, only the sum over these three columns;
First group by country.
Create one more group by quantity
Create one more group by name
Place weight in details and take the sum for all 3 groups if you need or only particular group
Supress tje details.
select
Users.UserId
,Users.FirstName + ' ' + Users.LastName AS
,[Month]
,[Day]
,x.[Przych]
,x.[Wych]
,x.[Przych] + [Wych] as [Ogół]
from
(select
CaseActionHistory.UserId
,month(CaseActionHistory.DateAdded) AS [Month]
,day(CaseActionHistory.DateAdded) AS [Day]
,sum(case when CaseActionHistory.CaseActionDefinitionId in (14,15,16) then 1 else 0 end) AS [Przych]
,sum(case when CaseActionHistory.CaseActionDefinitionId in (20,21,22,23,26) then 1 else 0 end) AS [Wych]
from CaseActionHistory
where CaseActionHistory.CaseActionDefinitionId in (14,15,16,20,21,22,23,26)
group by month(CaseActionHistory.DateAdded),day(CaseActionHistory.DateAdded), CaseActionHistory.UserId
order by month(CaseActionHistory.DateAdded) DESC,day(CaseActionHistory.DateAdded) DESC
OFFSET 0 rows
) AS x
inner join Users on x.UserId = Users.UserId
I'm trying to run out something out of this. My problem is: the results of such query are displayed like this:
User Month Day X
User1 7 31 6
User2 7 31 7
User3 7 31 9
User1 7 30 8
User2 7 30 7
User3 7 30 8
User4 7 31 10
User5 7 31 20
User6 7 31 23
User4 7 30 5
User5 7 30 7
User6 7 30 65
So in fact few Users are grouped into small groups which are displayed first, then 2nd group, etc. so I suppose there's a problem either with group by or order by.
As an addition I'd like to ask a question concerning parameters in SQL Server. Out of code below I'd like to set up 3 parameters:
User
Month
Day
But my problem is that when I set up details of parameter and I run it some values are multiplied. Same user is multiplied few times, same month, same day etc. also report itself is not reacting on any kind of change within parameters.
The main idea of a report is to show the number of phone calls done by every employee, each day, every month and to be able to compare results with others.
Calls are splitted into: outgoing and incoming. After every phone call employee adds to system an information regarding what phone call it was and what they managed to do during this phone call.
So in fact we are working on 2 tables in this case:
CaseActionHistory and Users
So the plan was to show the number of phone calls (incoming, outgoing and sum of those) for every day for every person.
Since CaseActionHistory table consits only ID of User which done the action and I'd like to show the person's name (which is placed in Users table obviously).
The problem is that the report should show around 20 Users one by one, so for 31st of June 20 Users one by one, for 30th 20 Users one by one etc, but it shows like 5 Users for 31st, then same Users for 30th, then next 5 Users for 31st etc (link to image showing the situation below)
http://img801.imageshack.us/img801/2088/7blu.png
Columns are:
UserId (to be replaced with UserName) Day Month Incming Outgoing Sum
The rows on the bottom for 31st July should be on the top of the list but they are not.
Welcome to stack overflow. A few things:
If your data is 'multiplying' may you just do a 'distinct' in your main select statement and determine if it is not your dataset repeating?
How are you applying parameters? They should be predicates and have nothing to do with groupings except indirectly. You may limit a set by a parameter but it will not affect your grouping directly, generally speaking.
What do you want to group by? Year, Month, (detail)?
SSRS starts out with a data connection (Data Source). You then apply a Data Set which is a query or proc. Which you have a query. You can apply a predicate to the main dataset with a 'where User = #User' or 'where User in (#User)'. The parameter will automatically be created if you do this in your dataset first with the '#(something)' creating a text parameter of said name. You see the Built In Fields, Parameters, Images, Data Sources, DataSets in the 'Report Data' view which you will use constantly in SSRS creation with 'Business Intelligence Development Studio'.
So a simple example would be that you want to add a group for the Day to your '(Details)' row. If you create a 'Table' element from the 'Toolbox' it will only have a single row called Details. Fill it with your X value and user. In the 'Design' surface at the bottom you will see 'Row Groups'. Right click on your 'Details' row and choose add parent group. Group by 'Day' check 'Add Group Header'. You now have another row that will be grouping by Day. You can repeat this process on the newly created group for a group for 'Month' and so and so on.