Separate 1 row data to multiple rows - sql

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.

Related

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.

How can I "dynamically" split a varchar column by specific characters?

I have a column that stores 2 values. Example below:
| Column 1 |
|some title1 =ExtractThis ; Source Title12 = ExtractThis2|
I want to remove 'ExtractThis' into one column and 'ExtractThis2' into another column. I've tried using a substring but it doesn't work as the data in column 1 is variable and therefore it doesn't always carve out my intended values. SQL below:
SELECT substring(d.Column1,13,24) FROM dbo.Table d
This returns 'Extract This' but for other columns it either takes too much or too little. Is there a function or combination of functions that will allow me to split consistently on the character? This is consistent in my column unlike my length count.
select substring(col1,CHARINDEX('=',col1)+1,CHARINDEX (';',col1)-CHARINDEX ('=',col1)-1) Val1,
substring(col1,CHARINDEX('=',col1,CHARINDEX (';',col1))+1,LEN(col1)) Val2
from #data
there is duplicate calculation that can be reduced from 5 to 3 to each line.
but I want to believe this simple optimization done by SQL SERVER.

DAX - selecting rows with partial match

I have a powerpivot table that contains 2 columns:
Column 1 contains strings.
Column 2 contains comma delimited strings.
I would like to be able to display all the rows from column 1 when rows from column 2 contains the selection from a filter or slicer. For example:
String Values
ABCD A,A,B
EFGH A,C
if A is selected I would display both rows, if B is selected I would display only row 1...etc.
I know I can split the records - but this is not practical for me - the above is only the top of the iceberg. VBA is out of the question since this will published in SharePoint. Anybody has an idea on how I could do that ? Thanks.
I found the solution in a blog from Javier Guillem:
http://javierguillen.wordpress.com/2012/02/10/simulating-an-approximate-match-vlookup-in-powerpivot/
If in my example the name of the table is "facts", I create a second unlinked table called dimRef that I populate with all possible values that I am interested to match: A,B,C,D...etc.
Then I define the measure M as:
M:=If ( Hasonevalue(facts[Values] ),
Calculate (
LASTNONBLANK (dimRef[String], 1 ),
Filter ( dimRef, SEARCH(dimRef[String],Values(facts[String]),1,0) > 0 )
)
)
I can then use the string column of the facts table and the measure in a pivot table and use dimRef as a selector. If filters the row as per the selection.
One small detail: the measure is not available in PowerView...Anybody knows why ?

SQL index match to find duplicate data

I have the following table
Code Name Task
aa jones DC
ab dave DC
aca james IF
aca james DC
ab trevor IF
aa jones IF
ag francis DC
ag francis IF
af derek SF
af derek DC
This is a very big table, above is just a quick example.
So, I would like some help finding the code and name that have completed a IF or SF task and a DC task.
I would like it to show where one person has touched both of these tasks. The hierarchy of the tasks is; it comes in as either a SF or IF then someone will do that, then off the back of that we receive a DC task, and I want the ones where it has been completed by the same person, with the same reference number.
I am able to do this in excel with an INDEX MATCH function, but this takes up a tremendous amount of calculation time due to the size of the table.
One way to approach this is using group by with a having. This is a flexible way of expressing these types of conditions:
select code, name
from table t
group by code, name
having sum(case when task = 'DC' then 1 else 0 end) > 0 and
sum(case when task in ('IF', 'SF') then 1 else 0 end) > 0;
Each condition in the having clause counts the number of rows that meet the particular condition. The first, for instance, counts the rows that match 'DC' and takes only the code, name pairs that have at least one such match.
SELECT code,name FROM YOUR_TABLE_NAME WHERE task = 'DC' AND (task = 'IF' OR task = 'SF') GROUP BY name
try this query
Gordon Linoff's query can be made easier under the hypothesys that IF and SF are synonym and cannot be both present for the same Code-Name couple, as the data provided by the OP suggests
SELECT code, name
FROM table t
GROUP BY code, name
HAVING SUM(CASE WHEN task IN ('IF', 'SF', 'DC') THEN 1 ELSE 0 END) = 2;
select code,name from (select distinct code,name from table1 where task='SF' or task='IF') as temp1 inner join (select distinct code as code2,name as name2 from table1 where task='DC') as temp2 on code=code2,name=name2;
I'm assuming that you have the table in table1. The code constructs two tables temp1 and temp2. temp1 contains those codes and names which have been assigned SF and IF. temp2 contains those codes and names which have been assigned DC. Finally, I join the two tables together to find code-name pairs in both tables. This is faster than in Excel because the database engine probably temporarily indexes the columns being joined on.
Actually, you can do this in Excel. You sort the table by code and name, then enter the following formulas (assuming "Code" is in A1):
D2=if(and(A2=A1,B2=B1,D1),true,or(C2="IF",C2="SF"))
E2=if(and(A2=A1,B2=B1,E1),true,C2="DC")
Select these two cells, and double-click the fill-handle (the little square at the bottom right of the selection). Then, with the two columns selected, copy, and then "Paste Special..." > "Values". Then, filter (Alt-D-F-F) for the rows with values in columns D and E being both true. That is the result you want. Select these rows and copy to a new sheet if desired.
Alternatively, you can follow the SQL "group by" solution given by Gordon, so that you do not need to sort: Create two new columns like the above, but:
D1: "D"
E1: "E"
D2=if(or(C2="IF",C2="SF"),1,0)
E2=if(C2="DC",1,0)
Then, "Insert" > "PivotTable", drag "Code" and "Name" to be row labels. Drag "D" to be under Values, click on it, "Value Field Settings...", and then select "Max". Do the same for "E", and then the rows with 1 in both D and E will be the result you want.

variable column

I have a database in MS-Access which has field names as "1", "2", "3", ... "10".
I want to select column 1 then when I click a button, column 2, column 3, ... and so on.
How to do that?
Actually i want to make a project in JSP.
Those are impractical field names, but you can use brackets to use them in a query:
select [1] from SomeTable where SomeId = 42
A basic rule for designing databases is that data should be in the field values, not in the field names. You should consider redesigning the table so that you store the values in separate rows instead, and have a field that specifies which item is stored in the row:
select Value from SomeTable where SomeId = 42 and ValueType = 1
This will enable you to use a parameterised query instead of creating the query dynamically.
Also, this way you don't have empty fields if you use less than ten items, and the database design doesn't limit you to only ten items.
Suppose I have a table like this
id name
1 name1
2 name2
3 name3
4 name4
5 name5
Now suppose I want to choose record 1 when button 1 is clicked, second record when button 2 is clicked and so on.
So I will write a query like
select * from MyTbl where id = #btnId .
Note:- #btnId will have the value 1 for Button 1, 2 for Button 2 etc.
Or you can use case statement.
This is just an idea for accomplishing the work but as others mentioned, you should be more specific for an accurate answer.