Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2009-07-08
7
Medium Priority
?
548 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 2000 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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

In this article we will get to know that how can we recover deleted data if it happens accidently. We really can recover deleted rows if we know the time when data is deleted by using the transaction log.
In part one, we reviewed the prerequisites required for installing SQL Server vNext. In this part we will explore how to install Microsoft's SQL Server on Ubuntu 16.04.
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…

610 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