Best Table Structure Design for Dynamic SQL statement - sql

I am looking for the best table structure to create a dynamic SQL statement like this below (which is not dynamic yet). I have to choose between
joined tables
a single row with all columns with the content comma-delimted which I then will parse
one large table with multiple rows per Cost Centre Activity Code
or anything else
In this example the key which all link to is: 'NSEA8102' which is a Cost Centre Activity code
SELECT
#pDate,
#pDate,
'NSEA8102', --Cost Centre Activity Code
ccg.tCCGroup,
SUM(logs.tTripHours) AS tTriphours,
'Actual EMV Hours Worked - ' + DATENAME(MONTH,#pDATE) + ' ' + CAST(YEAR(#pDate) AS CHAR(4))
FROM dbo.tblEMV_Logsheet AS logs INNER JOIN
dbo.tblLookup_EMVEquipment AS ccg ON logs.tEquipmentKey = ccg.tEquipmentKey
WHERE tDate BETWEEN #BMonth and #EMonth
AND (logs.tAreaCode in ('MINEE', 'SERVICE'))
AND (logs.tEventCode LIKE 'RASSTEEPS')
AND logs.tSourceLocationCode = 'STEEPS'
AND logs.tDestinationLocationCode = 'ERASSTSP'
AND (ccg.tCCGroup IN ('FADT', 'FPC800', 'FWA800'))
AND ccg.tValid = 1
GROUP BY ccg.tCCGroup
Any suggestion would be welcome. Thanks

Related

Joining SQL statements Atrium Syntess Firebird DB

I'm trying to get (one or multiple) number lines (PROGCODE) that are attached to an OBJECT (i.e. a building) that is connected to a Relation which in turn has a GC_ID (relation unique ID). I need all the buildings & progcodes connected to a relation ID in a firebird 2.5 database generated by my companies ERP system.
I can look through all the tables in the firebird database and run select queries on them.I like to think I have the join statement syntax down and I know how to find the unique ID belonging to a relation, unfortunately I'm unsure how I can find the correct table that houses the information I seek.
The table I think this data is in has the following fields:
GC_ID, DEVICE_GC_ID, USER_GC_ID, CODE, DESCRIPTION.
However when I query it using
select GC_ID, DEVICE_GC_ID, USER_GC_ID, CODE, DESCRIPTION
from AT_PROGCODE A
Then I get a description of the fields I'm trying to query.
i.e.
| GC_ ID : 100005 | DEVICE_GC_ID : 100174 | USER_GC_ID : 1000073 | DESCRIPTION: >description of what I'm trying to query< |
Can anyone shed some insight how I should handle this?
Update 7-09-2017
I spoke with the ERP consultant and was told the tables I needed (if anyone reading this is using syntess Atrium; the AT_BRENT table holds a description of all the tables.)
However, I've run into a new problem; the data I get from my sql query keeps streaming (it seems to never end with me stopping the script at 90 mil loops and the ERP program crashing if I ask for a count).
select A.GC_OMSCHRIJVING Bedrijf, A.GC_CODE ,M.GC_OMSCHRIJVING Werktitel,
M.TELEFOON1, M.TELEFOON2, M.MOBIEL, M.EMAIL,
M.URL, M.DOORKIES_NR, M.WERKLOCATIE, M.EMAIL_INTERN
from AT_MEDEW M , AT_RELATIE A
JOIN AT_MEDEW ON A.GC_ID = M.GC_ID
WHERE M.TELEFOON1 <> '' OR M.TELEFOON2 <> '' OR M.MOBIEL <> ''
Any ideas on what's the cause for my latest peril?
First I had to find the AT_BRENT table which holds all the descriptions for tables in Syntess Atrium
Then I was using a CROSS JOIN (as pointed out by https://stackoverflow.com/users/696808/bacon-bits )
I ended up using
select A.GC_OMSCHRIJVING Bedrijf, A.GC_CODE ,M.GC_OMSCHRIJVING Werktitel,
M.TELEFOON1, M.TELEFOON2, M.MOBIEL, M.EMAIL,
M.URL, M.DOORKIES_NR, M.WERKLOCATIE, M.EMAIL_INTERN
from AT_MEDEW M
JOIN AT_RELATIE A ON A.GC_ID = M.GC_ID
WHERE M.TELEFOON1 <> '' OR M.TELEFOON2 <> '' OR M.MOBIEL <> ''
Thank you all who helped.

Select information from different table SQL

SELECT Boeking.reisnummer, (aantal_volwassenen + aantal_kinderen) AS totaal_reizigers
FROM Boeking
WHERE Boeking.reisnummer = Reis.Reisnummer
AND Reis.Reisnummer = Reis.Bestemmingscode;
Table 1 (Boeking) has aantal_volwassen and aantal_kinderen, and Reisnummer.
Table 2 (Reis) has Reisnummer and Bestemmingscode.
I have to show the total of aantal_volwassenen and aantal_kinderen. But i also have to show Reis.bestemmingscode which comes from a different table. Currently i have to enter a parameter, how can i solve this?
You need to specify all the tables in the FROM part of your query. The tables should then be joined (JOIN) to get the data you need.
SELECT Boeking.reisnummer
,(aantal_volwassenen + aantal_kinderen) AS totaal_reizigers
,Reis.Bestemmingscode
FROM Boeking INNER JOIN Reis
ON Boeking.reisnummer = Reis.Reisnummer

How to make summary table of with respect to data in tables in access

This site is really good and I have got many help from u all.. So thank u for your help.
Now I have doubt. I have 3 tables called b1,b2,b3 in access having the same field but different data.
I want to make summary of the data in it in single table, like in b1 there is cable1 with 4m length, and in b3 there is cable1 with 8 m length..so in summary it should show cable 1 with 8+4 m length.
Any idea how to do it? Does union query help in this situation?
Purely based on your descriptioin and with no detail of your tables I would assume you are looking for something like this:
SELECT [CableType],
convert(nvarchar(5),B1.[Length]) + 'm +' + convert(nvarchar(5),B2.[Length])
+ 'm +' + convert(nvarchar(5),B3.[Length]) + 'm' as [Length]
FROM [B1]
join [B2] on [B1].[ID] = [B2].[ID]
join [B3] on [B1].[ID] = [B3].[ID]
I guess you have a column which holds the "Cable 1" description somewhere, also assuming you have an identifying column of some kind and your Lengths are stored as a number of some kind. This example would assume you always populate all 3 tables.

Looping SQL Script with Multiple Select Queries

I have a very specific problem relating to a query I am trying to write.
Basically the inventory table has about 450,000 rows of inventory items, showing the closing balance of each item of inventory for the end of each month. The other tables include a shipping table, which tracks daily data for all items of inventory coming in and leaving a specific location. Then we also have a production table, that tracks items of inventories that are used in the production process daily.
We are trying to create another table that tracks Weekly Inventories using the Shipping and Production Tables, and then calculating an end of month variance.
Here is my Pseudocode for the script I have had to write:
FOR EACH ROW IN INVENTORY_TABLE
#incoming_shipping = SELECT INCOMING_AMOUNT FROM SHIPPING_TABLE WHERE WEEK_OF_MONTH = 1
#outgoing_shipping = SELECT OUTGOING_AMOUNT FROM SHIPPING_TABLE WHERE WEEK_OF_MONTH = 1
#outgoing_production =SELECT OUTGOING_AMOUNT FROM PRODUCTION TABLE WHERE WEEK_OF_MONTH = 1
#closing_inventory=ROW.OpeningAmount + #incoming_shipping - #outgoing_shipping + #outgoing_production
INSERT INTO WEEKLY_INVENTORY (Opening_Amount,Closing_Amount)
'Compute Week 2 Value
#incoming_shipping = SELECT INCOMING_AMOUNT FROM SHIPPING_TABLE WHERE WEEK_OF_MONTH = 2
#outgoing_shipping = SELECT OUTGOING_AMOUNT FROM SHIPPING_TABLE WHERE WEEK_OF_MONTH = 2
#outgoing_production =SELECT OUTGOING_AMOUNT FROM PRODUCTION TABLE WHERE WEEK_OF_MONTH = 2
#closing_inventory=ROW.OpeningAmount + #incoming_shipping - #outgoing_shipping + #outgoing_production
INSERT INTO WEEKLY_INVENTORY (Opening_Amount,Closing_Amount)
'Continue doing this for the Four, Maybe 5 weeks that occur in a month.
NEXT
While it is correct, the query is a nightmare to execute and currently runs approximately 100 rows a minute. I have tried using Loops without Cursors, Cursors etc. and there is no obvious performance difference. I am wondering if there is a better way to write the script without using any Loops.
Thanks in advance for any help.
I believe something in the lines of would work for you:
INSERT INTO WEEKLY_INVENTORY(Opening_Amount, Closing_Amount)
SELECT
OPENING_AMOUNT,
(OPENING_AMOUNT +
(SELECT INCOMING_AMOUNT
FROM SHIPPING_TABLE
WHERE WEEK_OF_MONTH = ST.WEEK_OF_MONTH)
) - (
(SELECT OUTGOING_AMOUNT
FROM SHIPPING TABLE
WHERE WEEK_OF_MONTH = ST.WEEK_OF_MONTH) +
(SELECT OUTGOING_AMOUNT
FROM PRODUCTION_TABLE
WHERE WEEK_OF_MONTH = ST.WEEK_OF_MONTH)
)
FROM SHIPPING_TABLE ST
WHERE ST.WEEK_OF_MONTH <= 5
You don't have to loop over all rows in order to do this. You can calculate for each WEEK_OF_MONTH the value that needs to be inserted into WEEKLY_INVENTORY by using a combination of INSERT INTO SELECT.
In the SELECT part you build the values, for each week of month by using other SELECT statements to determine the value for Closing_Amount.
The above query would be a straightforward option from your code, but the same functionality as above can be achieved, with an increase in speed by using a JOIN, with the below query:
INSERT INTO WEEKLY_INVENTORY(Opening_Amount, Closing_Amount)
SELECT
ST.OPENING_AMOUNT
, (ST.OPENING_AMOUNT + ST.INCOMING_AMOUNT)-(ST.OUTGOING_AMOUNT + PT.OUTGOING_AMOUNT)
FROM SHIPPING_TABLE ST
INNER JOIN PRODUCTION_TABLE PT ON ST.WEEK_OF_MONTH = PT.WEEK_OF_MONTH
Depending on how your database schema is structured, the queries above might not work as you might need to use an aggregate function, SUM() I assume and also GROUPing BY product. But using just the pseudocode you provided, this is the translation into SQL.

SQL Query - combine 2 rows into 1 row

I have the following query below (view) in SQL Server. The query produces a result set that is needed to populate a grid. However, a new requirement has come up where the users would like to see data on one row in our app. The tblTasks table can produce 1 or 2 rows. The issue becomes when they're is two rows that have the same job_number but different fldProjectContextId (1 or 31). I need to get the MechApprovalOut and ElecApprovalOut columns on one row instead of two.
I've tried restructuring the query using CTE and over partition and haven't been able to get the necessary results I need.
SELECT TOP (100) PERCENT
CAST(dbo.Job_Control.job_number AS int) AS Job_Number,
dbo.tblTasks.fldSalesOrder, dbo.tblTaskCategories.fldTaskCategoryName,
dbo.Job_Control.Dwg_Sent, dbo.Job_Control.Approval_done,
dbo.Job_Control.fldElecDwgSent, dbo.Job_Control.fldElecApprovalDone,
CASE WHEN DATEDIFF(day, dbo.Job_Control.Dwg_Sent, GETDATE()) > 14
AND dbo.Job_Control.Approval_done IS NULL
AND dbo.tblProjectContext.fldProjectContextID = 1
THEN 1 ELSE 0
END AS MechApprovalOut,
CASE WHEN DATEDIFF(day, dbo.Job_Control.fldElecDwgSent, GETDATE()) > 14
AND dbo.Job_Control.fldElecApprovalDone IS NULL
AND dbo.tblProjectContext.fldProjectContextID = 31
THEN 1 ELSE 0
END AS ElecApprovalOut,
dbo.tblProjectContext.fldProjectContextName,
dbo.tblProjectContext.fldProjectContextId, dbo.Job_Control.Drawing_Info,
dbo.Job_Control.fldElectricalAppDwg
FROM dbo.tblTaskCategories
INNER JOIN dbo.tblTasks
ON dbo.tblTaskCategories.fldTaskCategoryId = dbo.tblTasks.fldTaskCategoryId
INNER JOIN dbo.Job_Control
ON dbo.tblTasks.fldSalesOrder = dbo.Job_Control.job_number
INNER JOIN dbo.tblProjectContext
ON dbo.tblTaskCategories.fldProjectContextId = dbo.tblProjectContext.fldProjectContextId
WHERE (dbo.tblTaskCategories.fldTaskCategoryName = N'Approval'
OR dbo.tblTaskCategories.fldTaskCategoryName = N'Re-Approval')
AND (CASE WHEN DATEDIFF(day, dbo.Job_Control.Dwg_Sent, GETDATE()) > 14
AND dbo.Job_Control.Approval_done IS NULL
AND dbo.tblProjectContext.fldProjectContextID = 1
THEN 1 ELSE 0
END = 1)
OR (dbo.tblTaskCategories.fldTaskCategoryName = N'Approval'
OR dbo.tblTaskCategories.fldTaskCategoryName = N'Re-Approval')
AND (CASE WHEN DATEDIFF(day, dbo.Job_Control.fldElecDwgSent, GETDATE()) > 14
AND dbo.Job_Control.fldElecApprovalDone IS NULL
AND dbo.tblProjectContext.fldProjectContextID = 31
THEN 1 ELSE 0
END = 1)
ORDER BY dbo.Job_Control.job_number, dbo.tblTaskCategories.fldProjectContextId
The above query gives me the following result set:
I've created a work around via code (which I don't like but it works for now) where i've used code to populate a "temp" table the way i need it to display the data, that is, one record if duplicate job numbers to get the MechApprovalOut and ElecApprovalOut columns on one row (see first record in following screen shot).
Example:
With the desired result set and one row per job_number, this is how the form looks with the data and how I am using the result set.
Any help restructuring my query to combine duplicate rows with the same job number where MechApprovalOut and ElecApproval out columns are on one row is greatly appreciated! I'd much prefer to use a view on SQL then code in the app to populate a temp table.
Thanks,
Jimmy
What I would do is LEFT JOIN the main table to itself at the beginning of the query, matching on Job Number and Sales Order, such that the left side of the join is only looking at Approval task categories and the right side of the join is only looking at Re-Approval task categories. Then I would make extensive use of the COALESCE() function to select data from the correct side of the join for use later on and in the select clause. This may also be the piece you were missing to make a CTE work.
There is probably also a solution that uses a ranking/windowing function (maybe not RANK itself, but something that category) along with the PARTITION BY clause. However, as those are fairly new to Sql Server I haven't used them enough personally to be comfortable writing an example solution for you without direct access to the data to play with, and it would still take me a little more time to get right than I can devote to this right now. Maybe this paragraph will motivate someone else to do that work.