Solved

Is it possible to write a SQL query with dynamic columns?

Posted on 2009-07-08
7
540 Views
Last Modified: 2012-05-07
I have a query for a revenue report, and want to know if there is a way to have the column names in my query auto-populated from a field value in a table.  The table I am using has unique groups names that I want to use as the column heading for each group so that I do not have to hard code the column name in my query.  There is a possibility that new group names will be added or existing ones could be changed.  Therefore, I need a query that will dynamically populate these group names for its respective columns.  In my query below, I assign a static column name to each field / sub-query.  I would like to dynamically pull the group name for each releated sub query.  I would also like to avoid hard-coding the group name in WHERE clause of the sub queries (e.g. AND d1.groupkey = 'INSPECTION').  Is there a way to do this?

THANK YOU in advance,

Parachute

Note:  The database is SQL Server 2000
SELECT DISTINCT 'Office' = a.office

	,'Customer' = a.name

	,'Invoice' = a.invno

	,'Jtype' = a.job_type

	,'Inv Date' = a.invdate

	,'Asset Sale' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 WHERE b1.invno = b.invno AND b1.itype = 'X'),0)

	,'Bid Job' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'BID JOB'),0)

	,'Inspection' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'INSPECTION'),0)

    ,'Labor' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b1.invno = b.invno AND b1.itype <> 'X' AND d1.groupkey = 'LABOR'),0)

	,'M&S Sale/Repairs' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'M&S SALE / REPAIRS'),0)

    ,'Mile/Sub' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'MILE/SUB'),0)

    ,'Re-Rent' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'RERENT EQUIPMENT'),0)

	,'Tool Rental' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X'	AND d1.groupkey = 'TOOL RENTAL'),0)

	,'Trucking' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'TRUCKING'),0)

	,'Waste Disposal' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 INNER JOIN inventory c1 ON b1.item = c1.item INNER JOIN categories d1 ON c1.cat = d1.category WHERE b.invno = b1.invno AND b1.itype <> 'X' AND d1.groupkey = 'WASTE DISPOSAL'),0)

	,'Other' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 WHERE b.invno = b1.invno AND b1.itype <> 'X' AND b1.item = 'COMMENT'),0)

	,'Gross Total' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 WHERE b.invno = b1.invno),0)

	,'Discount' = COALESCE(((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))) * (b1.discount * b1.discountable)/100,2)) FROM invoiceitem b1 WHERE b.invno = b1.invno)),0) 

	,'Net Total' = COALESCE((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))),2)) FROM invoiceitem b1 WHERE b.invno = b1.invno),0) - 

				   COALESCE(((SELECT SUM(ROUND(((b1.quant * b1.min_chg) + (b1.quant * (b1.aday * b1.adamt))) * (b1.discount * b1.discountable)/100,2)) FROM invoiceitem b1 WHERE b.invno = b1.invno)),0)

FROM invoicehdr a

INNER JOIN invoiceitem b ON a.invno = b.invno

INNER JOIN inventory c ON b.item = c.item

INNER JOIN categories d ON c.cat = d.category

LEFT OUTER JOIN taxcode e ON a.taxcode = e.taxcode 

WHERE a.invdate BETWEEN '2009-04-01 00:00:00.000' AND '2009-06-30 23:59:59.000'

ORDER BY a.office, a.name, a.invno, a.invdate

Open in new window

0
Comment
Question by:parachute_505
  • 4
7 Comments
 
LVL 57

Accepted Solution

by:
Raja Jegan R earned 500 total points
ID: 24809824
Yes.. You have and try like this.
Using a simple query for explanation:

In the example below, you can
1. Dynamically pass column selections @ur_dynamic_column
2. Dynamically pass column names / results @ur_dynamic_column_name
3. Dynamically pass where condition variables @a
4. Dynamically pass AND Conditions stored in some table or variable (SELECT dynamic_where_condition from some_table where a = 1)  or @b like that.

Hope this helps
declare @sql nvarchar(2000);

set @sql = ' select a, ' + @ur_dynamic_column + ' ,c as ' + @ur_dynamic_column_name + ' from ur_table where a = ' + @a + (SELECT dynamic_where_condition from some_table where a = 1) 

exec sp_executesql @sql;

Open in new window

0
 
LVL 57

Expert Comment

by:Raja Jegan R
ID: 24809828
Since the database is SQL Server 2000, a slight modification required.
declare @sql varchar(2000);

set @sql = ' select a, ' + @ur_dynamic_column + ' ,c as ' + @ur_dynamic_column_name + ' from ur_table where a = ' + @a + (SELECT dynamic_where_condition from some_table where a = 1) 

exec (@sql);

Open in new window

0
 

Author Comment

by:parachute_505
ID: 24817029
rrjegan17:

I don't quite understand how I can incorporate what you wrote into my query.  

Parachute
0
 
LVL 57

Expert Comment

by:Raja Jegan R
ID: 24819916
>> Therefore, I need a query that will dynamically populate these group names for its respective columns. In my query below, I assign a static column name to each field / sub-query.  

If I understood correctly, then you mean to say that column names to be displayed will be changed dynamically in your SELECT query. If that is the case, then it is step no 2 in comment 24809824.

Follow the example provided earlier.

>> I would like to dynamically pull the group name for each releated sub query.  
I would also like to avoid hard-coding the group name in WHERE clause of the sub queries (e.g. AND d1.groupkey = 'INSPECTION').

In that case I assume that your WHERE clause will be dynamically added to your query. Kindly follow step no 3 and 4 above in that case.

Hope this clarifies.
Revert if I need to explain it in more detail
0
 
LVL 57

Expert Comment

by:Raja Jegan R
ID: 25562083
Split between 24809828 and 24819916
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Access Query 4 34
Date Differences SSRS 3 44
Oracle Subquery bad Join 11 43
how to extract a number from a MS SQL server string. 39 64
PL/SQL can be a very powerful tool for working directly with database tables. Being able to loop will allow you to perform more complex operations, but can be a little tricky to write correctly. This article will provide examples of basic loops alon…
This article describes how to use the timestamp of existing data in a database to allow Tableau to calculate the prior work day instead of relying on case statements or if statements to calculate the days of the week.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now