Converting data from columns to rows in qlikview - qlikview

I have the xlsx sheet which has data for every month in the columns. I want to convert it to rows while I load it to QlikView
First Name
Last Name
Home Owner
Mortgage
44562
44593
44621
44652
A
FSFD
Y
Y
34343
48768
87788
878878
DGD
KJJHK
Y
N
5454
454
4545
74878
FDQE
TERTER
N
N
78676
787897
454654
7787
RTE
YRTYZ
Y
N
78634
545
4787
5744
SAS
TRGFV
N
N
6764
54465
1215
4878

In this case you can use CrossTable load.
From the documentation:
The crosstable prefix is used to turn a cross table into a straight table, that is, a wide table with many columns is turned into a tall table, with the column headings being placed into a single attribute column.
In your case we can have script like this:
Data:
CrossTable([Month], [Value], 4)
LOAD
[First Name],
[Last Name],
[Home Owner],
Mortgage,
[44562],
[44593],
[44621],
[44652]
FROM
[C:\Users\USER\Documents\data.xlsx]
(ooxml, embedded labels, table is Sheet1)
;
Once the script the is reloaded the resulted table will be:
CrossTable(Month, Value, 4) is the important bit. The values in the the brackets are stating that: After the 4th column, move the top row (header) as column and name the new column Month, name the values against it Value (you can see the new Month and Value columns in the screenshot). Month and Value are made-up names and the can be named whatever you want.

Related

SQL: Change query output to have two separate columns from having rows with 2 values

For some reason my query output is grouping together 2 columns into 1, and putting the 2 values in the same row like this:
PATIENT_NAME
--------------------------------------------------------
INSURANCE
-------------------------
Aimie Pepsodent
Manulife
Aka Fresh
Blue Cross
Apple Addaye
Blue Cross
But I want them to appear in two separate columns like my teacher's output:
PATIENT_NAME INSURANCE
-------------- ----------------
Apple Addaye Blue Cross
Roy Alflush No Insurance
Shane Cane No Insurance
Is there a way I can change it to this?
Right now my sql query looks like this:
select (fname||' '||lname) patient_name,
(nvl(l4_insurance_cos.company_name, 'No Insurance')) insurance
from l4_patients
left join l4_insurance_cos
on l4_patients.ins_id = l4_insurance_cos.id
order by l4_patients.lname;
This is a pure SQLPlus display issue. The size of the line is too small for the two columns to fit in it, so SQLPlus splits the results on two lines.
You need to adjust the linesize of your terminal, and/or the display width of each column - by default, it corresponds to the maximum length of the resultset column (if you concatenate two columns in the query, that's the sum of the length of the two columns, with a limit of 4000 bytes for varchars).
The actual values will depend on your terminal and table definition, but here is an example:
set linesize 140 -- allow a total of 140 characters per line
column patient_name format a80 -- 80 characters for column "patient_name"
column insurance format a60 -- 60 characters for column "insurance"
Then, you can run your query.

Populate NULL Values based on Array Formula

New user, so apologies in advance for bad formatting.
Essentially what I'm trying to do is be able to populate the staff_hours column where it equals NULL with the one value that IS NOT NULL. As you can see from the screenshot, there will only be one person who staffs an open cl_hole_staffing_no and as a result will have a start_dt (with time) and end_dt (with time) along with staff_hours. 16 people were offered a shift, and the person in row 15 accepted it is what is going on here.
The ideal output would be the staff_hours column is populated with the amount of time of the one person who ended up taking the open job, so 24.00 in this example. How can I write a formula to do this? I was thinking something like an array function in Excel, but am not sure how to do that in SQL.
Your explanation is a bit confusing about what you are really trying to achieve. However I think that what you really want is just to populate the staff_hours column, which can be achieved with the following:
UPDATE
your_table_name
SET
staff_hours = 24
WHERE
staff_hours is NULL;
EDIT
I get it now. You want to operate with the two dates and extract the amount of hours between them. Since you are in sql-server you can actually define a Computed Column in which you can use the values from other columns to compute the value you want.
You will need to create your table again. (The example below contains only the necessary attributes for it to work)
CREATE TABLE your_table_name
( id INT IDENTITY (1,1) NOT NULL
, staff_start_dt DATETIME
, staff_end_dt DATETIME
, staff_hours AS DATEDIFF(hh, staff_start_dt , staff_end_dt)
);
Now every time you insert a record on the table with both staff_start_dt and staff_end_dt, the column staff_hours will automatically compute the number of hours between the two dates.
[pre]
Code (vb):
A B C
1 10 X X
2 11 A Y
3 12 Y Z
4 13 B
5 14 B
6 15 Z
[/pre]
Assuming that the rows in Col A is Named "datarange"
And your criteria is in C1:C3
The following formula will return an array {10,12,15}
=SMALL(COUNTIF(C1:C3,B1:B6)*datarange, ROW(INDEX(A:A,SUMPRODUCT(--(COUNTIF(C1:C3,B1:B6)=0))+1):INDEX(A:A,ROWS(datarange))))
COUNTIF(C1:C3,B1:B6)*datarange returns {10;0;12;0;0;15}
The segment ROW(INDEX(....):INDEX(...)) returns {4;5;6}, indicating the number of non-zero values.
The SMALL() function then returns the 4th smallest, 5th smallest and 6th smallest values.
One disadvantage with this approach is that you get a sorted sub-list. Perhaps that would work for you.

How to combine a row of cells in VBA if certain column values are the same

I have a database where all of the input from the user (through a userform) gets stored. In the database, each column is a different category for the type of data (ex. date, shift, quantity, etc) and the data from the userform input gets put into its corresponding category. For some of the data, all the data is the same except for the quantity. I was wondering how I could combine these rows into one and add the quantities to each other for the whole database (ex. combining the first and third data entries). I have tried playing around with a couple different loops but can't seem to figure anything out.
Period Date Line Shift Type Quantity
4 x 2 4/3/18 A 3 14 18
4 x 2 4/3/18 A 3 13 12
4 x 2 4/3/18 A 3 14 15
Thank you!
If you're looking to modify the underlying database, you might be able to query the data into the format you want by including all the other columns in a GROUP BY statement, save the result to another table, then replace the original table with the properly formatted one.
If you have the data in Excel and you just want to view it with the duplicate rows summed, a Pivot Table would be a good choice. You can select all the other columns as rows for the Pivot Table and sum of Quantity as the values.

Separate 1 row data to multiple rows

I currently have a table that contains multiple rows and columns like bellow (the data in the row is somewhat grouped)
ID Column1_1 Column1_2 Column1_3 Column1_4 Column2_1 Column2_2 Column2_3 etc.
1 data11 data12 data13 etc.
2 data21 data22 etc.
3 data31 etc.
I need this table to be exported in an excel that looks like this:
ID Column DATA
1 Column1_1 data11
1 Column1_2 data12
1 Column1_3 data13
1 Column1_4 data14
2 Column2_1 data21
2 Column2_2 data22
I was thinking to export it in a big excel first and then create multiple sheets. But can I use group by in excel?
You can use UNPIVOT
SELECT
ID, ColumnName, DataValue
FROM
YourTable
UNPIVOT
(
DataValue FOR ColumnName IN (Column1_1, Column1_2, Column1_3, Column1_4, Column2_1, Column2_2, Column2_3.........)
)
AS unpvt;
https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot
You are normalizing the data and you have a field just for it called Row Normalizer. (Official doc is here).
Admittedly, the first few times you pull your hair with an outdated vocabulary, just because Microsoft re-invented the wheel by calling this operation a 'pivot'.
In your case the Typefield is "Column", the Fieldname are the "Column1_1"s or whatever the column are named in your input, the Type is "Column1_1" or whatever you want to write in the column named Column on your output, and New field is "DATA" or whatever you want to name the output denormalized column.
Of course, there is a bottom button to help you, however, as it seams to be your first time, I suggest you try manually with two or tree column before.

SSRS - Is there a way to have a table split by a page break to appear on the same page?

I am creating a report using MS Report Builder 3.0. For this report, I have a stored procedure built that filters down to the specific rows needed, and then I use a row group to group on a particular field (pass_no). The table that is displayed is 2 columns and 3 rows within the row group. The basic description of what I want to accomplish is instead of the rows running onto the next page, I want the rows to continue on the same page in a new set of 2 columns. Think of it like a newspaper where the text continues in a new column rather than running down onto the next page.
For the example I'm going to use here, there are 12 rows of data returned by the SP, and 8 unique values in the pass_no column which is what my row group is grouped on. So in the report I end up with 8 groups of 3 rows. I'm aiming to have the table display 6 pass_no values (so 6 groups of 3 rows) before, for lack of better terminology, starting a new table.
My first approach at this has been to create a column group and set the grouping expression to the following:
=Floor((RowNumber(Nothing) - 1) / 6)
While this works in creating a new set of 2 columns, the split for the new columns is based on the row number from the raw data returned by the SP rather than the number of rows sets created by the row group. So because there are 12 rows returned, and the 6th and 7th rows have the same pass_no value, the second set of columns duplicates that 1 set of data. Also, the top 6 rows of the second column set are blank with the second set of values appearing below the first set.
If I add an additional column group where it is also grouping by pass_no, then I don't get the duplicate values, but I do get a pair of columns for each pass_no as well (as would be expected). I've tried modifying the expression above a bit and changed Nothing to the row group name and have tried the table name, but neither of them have yielded the desired result.
I can't alter the SP to do the grouping there because there are other column values that are not identical and I pull that data into a cell value expression within the table using Join(LookupSet()).
I have also considered creating 2 tables and applying a filter to the table so the first table only displays the first 6 results and the second table displays the remaining results, but that also looks at the raw data rather than the groupings and TOP N can't be used on pass_no as it's a text value, not an integer. This would also cause problems if I need to go to 3 tables.
So long story short, is there a way to do a table break rather than a page break or to overflow columns onto the same page rather than onto a new page?
Here's the pertinent portions of the Dataset:
http://sqlfiddle.com/#!2/5082b/1
PASS_NO MASTERTRAN TRANS_NO DESCRIPTION IS_MOD
7913019000 4931019000 4931019000 General Admission Adult 0
7914019000 4932019000 4932019000 Sea Turtle Hosp Adult 0
7914019000 4932019000 4933019000 2:00 PM SEA TURTLE HOSP 1
7916019000 4934019000 4934019000 Sea Turtle Hosp Child 0
7916019000 4934019000 4935019000 2:00 PM SEA TURTLE HOSP 1
7917019000 4934019000 4934019000 Sea Turtle Hosp Child 0
7917019000 4934019000 4935019000 2:00 PM SEA TURTLE HOSP 1
7918019000 4934019000 4934019000 Sea Turtle Hosp Child 0
7918019000 4934019000 4935019000 2:00 PM SEA TURTLE HOSP 1
7922019000 4936019000 4936019000 General Admission Child 0
7923019000 4936019000 4936019000 General Admission Child 0
7924019000 4936019000 4936019000 General Admission Child 0
I think your data presents a bit of a problem.
As you've already figured out, typically for this sort of setup you'd set up a row group with an expression like:
=(RowNumber(Nothing) - 1) Mod 6
And a column group expression like:
=Ceiling(RowNumber(Nothing) / 6)
This would create a six row tablix that would grow horizontally as required.
See this SO question for a similar example.
However, you currently have the requirement of also grouping by another column - pass_no in your case. Normally you can approximate a group-level row number with an expression like:
=RunningValue(Fields!pass_no.Value, CountDistinct, "DataSet1")
Unfortunately, when you try to add this into one of the grouping expressions like:
=Ceiling(RunningValue(Fields!pass_no.Value, CountDistinct, "DataSet1") / 6)
You get the following error:
A group expression for the tablix 'Tablix1' includes the aggregate
function RunningValue. RunningValue cannot be used in group
expressions.
Based on all this, my recommendation is to try and get a Dataset that has one row per pass_no value and base the tablix on this, with the above row/column grouping expressions, i.e. no need to group on multiple pass_no rows. So in your example it would have eight rows. You could then have a separate Dataset with all the individual rows and use a lookupset function to concatenate the description, etc.
Your other option is to try and get everything on one Dataset only, including the aggregates as required. This might not be possible, but for description at least you can leverage any of the various techniques here to get a delimited list. Once you have this list you can replace the delimiter with vbCrLf to split it back over multiple rows.
All this is a very long-winded way of saying that I don't know if your requirement is possible with your data, but if you look at having at least one Dataset with one row per pass_no you should be able to make it work.