Solved

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

Posted on 2009-07-08
7
542 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.

Question has a verified solution.

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

Written by Valentino Vranken. Introduction: The first step of creating a SQL Server Reporting Services (SSRS) report involves setting up a connection to the data source and programming a dataset to retrieve data from that data source.  The data…
A recent questions about how to add SSRS named instances, couldn't find any that talks about SQL server 2008, anyway I decided to help by creating some screen shots. The installation is straightforward, you just pop the SQL server 2008 installati…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

810 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