I have to write a query to get the following data as result.
I have four columns in my database. ID is not null, all others can have null values.
EMP_ID EMP_FIRST_NAME EMP_LAST_NAME EMP_PHONE
1 John Williams +123456789
2 Rodney +124568937
3 Jackson +124578963
4 Joyce Nancy
Now I have to write a query which returns the columns which are not null.
I do not want to specify the column name in my query.
I mean, I want to use SELECT * FROM TABLE WHERE - and add the filter, but I do not want to specify the column name after the WHERE clause.
This question may be foolish but correct me wherever necessary. I'm new to SQL and working on a project with c# and sql.
Why I do not want to use the column name because, I have more than 250 columns and 1500 rows. Now if I select any row, at least one column will have null value. I want to select the row, but the column which has null values for that particular row should not appear in the result.
Please advice. Thank you in advance.
Regards,
Vinay S
Every row returned from a SQL query must contain exactly the same columns as the other rows in the set. There is no way to select only those columns which do not return null unless all of the results in the set have the same null columns and you specify that in your select clause (not your where clause).
To Anders Abels's comment on your question, you could avoid a good deal of the query complexity by separating your data into tables which serve common purposes (called normalizing).
For example, you could put names in one table (Employee_ID, First_Name, Last_Name, Middle_Name, Title), places in another (Address_ID, Address_Name, Street, City, State), relationships in another, then tiny 2-4 column tables which link them all together. Structuring your data this way avoids duplication of individual facts, like, "who is John Williams's supervisor and how do I contact that person."
Your question reads:
I want to get all the columns that don't have a null value.
And at the same time:
But I don't want to specify column names in the WHERE clause.
These are conflicting goals. Your only option is to use the sys.tables and sys.columns DMVs to build a series of dynamic SQL statements. In the end, this is going to be more work that just writing one query by hand the first time.
You can do this with a dynamic PIVOT / UNPIVOT approach, assuming your version of SQL Server supports it (you'll need SQL Server 2005 or better), which would be based on the concepts found in these links:
Dynamic Pivot
PIVOT / UNPIVOT
Effectively, you'll select a row, transform your columns into rows in a pivot table, filter out the NULL entries, and then unpivot it back into a single row. It's going to be ugly and complex code, though.
Related
new to stack overflow as my job has me doing more SQL querying than I'm use to (super basic queries). And since this is the best online resource....:)
Preamble...my company has developed an SQL database that contains a giant table of tables. In other words, they extracted a series of tables (200+) from external sources and put them all into one massive table to be used for reporting purposes in other systems. For example, if one of these external tables has 5 fields and 10 rows of data, that translates to 50 rows in this 'table of tables' (Table1, Field1, Value...Table1, Field2, Value....TableX, FieldX, Value...etc.)
Requirement...I need to 'pivot' the data for the purposes of getting a list of all the fields in all the tables. In other words ignore the values (just TableX, FieldX). I need to do this in order to find 'like' fields across all the tables. Being new to using PIVOT in SQL queries, I know the basic structure of the SQL query, but I'm getting lost in the organization of it. Maybe I don't even use PIVOT. Here's what I have...
SELECT * from (
SELECT [FieldName],[iModelTable]
FROM [H352090DataMart].[dbo].[HA_iModelTableData]
PIVOT (MAX([FieldName]) FOR [iTableName] IN
(
--not sure what would go here if anything
)
) AS pvt
Any help is greatly appreciated.
Austin.
Nevermind. I figured it out. Is was as simple as using the DISTINCT function. As I said, I'm a bit of a noob when it comes to scripting. So for those who read this post, the answer is as follows (the ORDER BY is extra)...
SELECT DISTINCT
[iModelTable]
,[FieldName]
FROM [H352090DataMart].[dbo].[HA_iModelTableData]
ORDER BY iModelTable
I am practicing SSIS and currently working on Pivot transformation. Here's what i am working on.
I created a Data Source (Table name: Pivot) with the following data.
Using SSIS, i created a package for Pivoting the data to have the following columns
PersonID --- Product1 --- Product2 --- Product3.
Here's where am at, I was able to create the pivot data to text file. But The output is not grouped by PersonID.
My Current Output is
As we can see the Transformation does not group the based on
SetKey(PersonID : PivotUsage =1)
The output i am hoping to get is
Where the data is grouped based on PersonID.
What am i missing here?
Edit:
Going back to the example i was following, I re-ordered the input data as follows.
Does the Input data need to be in this order/pattern, every time? Most of the examples i came across follow the similar pattern.
Yes, the input data needs to be sorted by whatever you're pivoting on:
To pivot data efficiently, which means creating as few records in the
output dataset as possible, the input data must be sorted on the pivot
column. If the data is not sorted, the Pivot transformation might
generate multiple records for each value in the set key, which is the
column that defines set membership. For example, if the dataset is
pivoted on a Name column but the names are not sorted, the output
dataset could have more than one row for each customer, because a
pivot occurs every time that the value in Name changes.
That's a direct quote from the Pivot Transformation documentation on MSDN. (Emphasis added.)
When I first read this answer, I thought that the sorted column should be the one with PivotUsage=2 in the pivot. That's what I understood the pivot column to be. However, what finally worked for me was to sort by a column with pivot usage=1. It's a column I would group by if writing the sql by hand.
Scenario
A very large size query returns a lot of fields from multiple joined tables.
Some records seem to be duplicated.
You accomplish some checks, some grouping. You focus on a couple of records for further investigation.
Still, there are too much fields to check each value.
Question
Is there any built-in function that compares two records, returning TRUE if the records match, otherwise FALSE and the set of not matching fields?
The CHECKSUM function should help identify matching rows
SELECT CHECKSUM(*) FROM table
May be this is what you are looking for:
SELECT * FROM YourTable
GROUP BY <<ColumnList>>
HAVING COUNT(*) > 1
Just developing on the suggestion provide by Podiluska to find the records which are duplicates
SELECT CHECKSUM(*)
FROM YourTable
GROUP BY CHECKSUM(*)
HAVING COUNT(*) > 1
I would suggest that use the hashbytes function to compare rows.It is better than checksum.
What about creating a row_number and parttion by all the columns and then select all the rows which are having the rn as 2 and above? This is not slow method as well as it will give you perfect data and will give the full row's data which is being duplicated.I would go with this method instead of relying on all the hashing techniques..
I'm back with another (possibly) silly question. sorry.
I have a pretty complicated query which joins 4 tables and computes the sum of a column based on the other two columns in two tables. the result returned is like this:
Image http://eternalvinay.iocleicester.com/blahblah.png
Now, I want the results to be like the right hand side of the image. the number rows per month/year might change though its 4 for now.
I am creating a temporary table as:
Declare #TmpTable (id int identity, AnsSum float, AnsMonth int, AnsYear int)
to store the values from image --> table1. However, I cant figure out how to convert those rows into the format required by table 2.
So, Any hints on this please?
Thanks so much..
ps: I tried to google and related questions here, no luck.
pss: I am not expecting the exact answer too, i am quite interested to learn new things so if you know where i can learn to do this, a push in the right direction, that would be great too!
You could use cross apply to get all the values in a comma delimted format in a single column. instead of "4" different columns. The problem is this "4" cannot be defined everytime. it may increase or decrease and it is not advisable to have this as columns.
SELECT DISTINCT AnaMonth, anayear, [DerivedColumn] FROM #TmpTable A
CROSS APPLY
(
SELECT AnaSum + ',' FROM #TmpTable B
WHERE A.AnaMonth = B.AnaMonth
AND A.AnaYear = B.AnaYear
FOR XML PATH('')
) AS C (DerivedColumn)
You will get [6.0000, 1.000, 8.0000, 5.0000] in one column for month 5 and year 2010 etc ... You could use this as a table to query for any particular month.
Hope this helps
So you have normalized data and you want to pivot the result set to create repeating groups.
You could use PIVOT but you'd need some other attribute in your base table to define the four columns.
I would recommend do not pivot this query in SQL. Just do the query against the database and get four rows per month/year. Then write code in your application to aggregate the results by month/year.
So my goal here is to have a single search field in an application that will be able to search multiple tables and return results.
For example, two of these tables are "performers" and "venues" and there are the following performers: "John Andrews","Andrew Smith","John Doe" and the following venues: "St. Andrew's Church","City Hall". Is there a way to somehow return the first two performers and the first venue for a search of "Andrew"?
My first thought was to somehow get all the tables aggregated into a single table with three columns; "SearchableText","ResultType","ResultID". The first column would contain whatever I want searched (e.g. Performer name), the second would say what is being shown (e.g. Performer) and the third would say the item's ID (note: all my tables have auto-incrementing primary keys for ease). The question for this idea is it possible to somehow do this dynamically or do I have to add code to have a table that automatically fills whenever a new row is updated/added/deleted from the performers and venues table (perhaps via trigger?).
My application is written in MSAccess (I know, I know, but I have no choice) on top of a SQL Server backend. I'd prefer this happen through MSAccess so I don't have to have a "searchme" table sitting on my SQL Server but any good result is acceptable :)
I think you are looking for the "union" sql keyword
I'd use full text indexing in SQL server, have a single table with your searchable text, and forign keys in your main tables that link to the search table. This way you can order your results by relevance.
I think you have a schema problem. Querying a UNION is almost always evidence of that (though not in all cases).
The question to me is:
What are you returning as your result?
If you find a person, are you displaying a list of people?
Or if you find a venue, a list of venues?
Or a mix of both?
I would say that if you want to return a list of both, then you'd want something like this:
SELECT tblPerson.PersonID, tblPerson.LastName & ", " & tblPerson.FirstName, "Person"
FROM tblPerson
WHERE tblPerson.LastName LIKE "Andrew*"
OR tblPerson.FirstName LIKE "Andrew*"
UNION
SELECT tblVenue.Venue, tblVenue.Venue, "Venue"
FROM tblVenue
WHERE tblVenue.Venue LIKE "Andrew*"
ORDER BY Venue
This will give a list of the matches indicating which is a person and which a venue, and allow you to then select one of those and open a detail view (by checking the value in the third field).
What you definitely don't want to do is this:
SELECT tblPerson.PersonID, tblPerson.LastName & ", " & tblPerson.FirstName, "Person"
FROM tblPerson
UNION
SELECT tblVenue.Venue, tblVenue.Venue, "Venue"
FROM tblVenue
then saving that and trying to query it on the 2nd column. That will be extremely inefficient. You want your WHERE clause to be on fields that can be searched via the index, and that means each subquery of your UNION needs to have an appropriate WHERE clause.