Solved

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

Posted on 2009-07-08
7
545 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you find yourself in this situation “I have used SELECT DISTINCT but I’m getting duplicates” then I'm sorry to say you are using the wrong SQL technique as it only does one thing which is: produces whole rows that are unique. If the results you a…
In this article I will describe the Backup & Restore method as one possible migration process and I will add the extra tasks needed for an upgrade when and where is applied so it will cover all.
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

689 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