SQL decode on column4 but only when column5 is distinct - sql

I need to change the sum(decode()) expressions that are like
SUM(Decode(vcon.WAGON_TYPE_CODE,'MS',1,0))
to something that counts rows with vcon.WAGON-TYPE-CODE = 'MS' but only when wag.ACI-TAG-NO is distinct.
So if two columns look like this
vcon.WAGON_TYPE_CODE wag.ACI_TAG_NO
MS HI1111
SS C99999
MS HI1111
MS HI7777
SS HI8888
MS HI6666
The expression needs to return the number 3 rather than 4 as SUM(Decode(vcon.WAGON_TYPE_CODE,'MS',1,0)) currently does.
Any suggestions?
querySELECT = "SELECT "
querySELECT = querySELECT & "trn.WID_DATE, "
querySELECT = querySELECT & "trn.MINE_CODE, "
querySELECT = querySELECT & "trn.TRAIN_CONTROL_ID, "
querySELECT = querySELECT & "trn.NUM_CARS as HBD_Car_Count, "
querySELECT = querySELECT & "SUM(Decode(vcon.WAGON_TYPE_CODE,'MS',1,0)) M_Series, "
querySELECT = querySELECT & "(SUM(Decode(vcon.WAGON_TYPE_CODE,'SS',1,0))-SUM(Decode(wag.ACI_TAG_NO,'HI0000',1,0))) S_Series, "
querySELECT = querySELECT & "SUM(Decode(vcon.WAGON_TYPE_CODE,'CS',1,0)) C_Series, "
querySELECT = querySELECT & "SUM(Decode(wag.ACI_TAG_NO,'HI0000',1,0)) as No_Tag, "
querySELECT = querySELECT & "(COUNT(1) - trn.NUM_CARS) DB_Mismatch "
queryFROM = "FROM widsys.consist con, widsys.train trn, widsys.wagon wag, widsys.v_consist_ore_detail vcon "
queryWHERE = "WHERE trn.TRAIN_RECORD_ID = con.TRAIN_RECORD_ID "
queryWHERE = queryWHERE & "AND con.WAGON_ID = wag.WAGON_ID "
queryWHERE = queryWHERE & "AND ((vcon.CONSIST_ID=con.CONSIST_ID) "
queryWHERE = queryWHERE & "AND trn.MINE_CODE In (" & mine & ") "
queryWHERE = queryWHERE & "AND (trn.DIRECTION='N') "
queryWHERE = queryWHERE & "AND (wag.ACI_TAG_TYPE In ('CONTROL','SLAVE','ORE')) "
queryWHERE = queryWHERE & "AND (trn.WID_DATE>={ts '" & startDate & "'} "
queryWHERE = queryWHERE & "AND trn.WID_DATE<={ts '" & endDate & "'})) "
queryGROUPBY = "GROUP BY trn.WID_DATE, trn.MINE_CODE, trn.TRAIN_CONTROL_ID, trn.NUM_CARS "
queryORDERBY = "ORDER BY trn.WID_DATE DESC"

I think the following should work (this count the distinct wag.ACI_TAG_NO only when vcon.WAGON_TYPE_CODE='MS') :
COUNT(DISTINCT Decode(vcon.WAGON_TYPE_CODE,'MS',wag.ACI_TAG_NO,NULL))
e-g:
SQL> WITH data AS (
2 SELECT 'MS' WAGON_TYPE_CODE, 'HI1111' ACI_TAG_NO FROM DUAL UNION ALL
3 SELECT 'SS', 'C99999' FROM DUAL UNION ALL
4 SELECT 'MS', 'HI1111' FROM DUAL UNION ALL
5 SELECT 'MS', 'HI7777' FROM DUAL UNION ALL
6 SELECT 'SS', 'HI8888' FROM DUAL UNION ALL
7 SELECT 'MS', 'HI6666' FROM DUAL
8 )
9 SELECT COUNT(DISTINCT decode(WAGON_TYPE_CODE,'MS',ACI_TAG_NO,NULL))
10 FROM DATA
11 ;
COUNT(DISTINCTDECODE(WAGON_TYP
------------------------------
3
Cheers,
--
Vincent

You could use a subquery that filters duplicate tags. Your query is pretty complex, but this would calculate just the sum you're looking for:
SELECT SUM(Decode(sub.WAGON_TYPE_CODE,'MS',1,0))
FROM (
SELECT DISTINCT vcon.WAGON_TYPE_CODE, wag.ACI_TAG_NO
FROM widsys.wagon wag
INNER JOIN widsys.consist con
ON con.wagon_id = wag.wagon_id
INNER JOIN widsys.v_consist_ore_detail vcon
ON vcon.CONSIST_ID = con.CONSIST_ID
) sub
The DISTINCT makes sure there is only one row per (wagon_type,aci_tag_no) combination.

Related

Instead of 'table variable+column name =' is there any method to simplify that?

Instead of table variable+column name = is there any method to simplify that?
update [hopi].[dbo].[hdc
set dostat = 'i'
from [hopi].[dbo].[hdc] as b
inner join [hopi].[dbo].hperson as a
on b.hpercode = a.hpercode
inner join [hopi].[dbo].[hprocm] as c
on b.proccode = c.proccode
where b.dostat = 'a'
and datepart(yy,b.dodate)='" & yr & "'
and datepart(mm,b.dodate)='" & mnth & "'
and datepart(dd,b.dodate)='" & dy & "'
and a.last= '" & & "'enter code here
and a.first= '" & & "'
and (c.procdesc='prec' or c.procdesc='pros' or c.procdesc='vat' or c.procdesc='vet' or c.procdesc='pak' or c.procdesc='pren' or c.procdesc='maser' or c.procdesc='lolo' or c.procdesc='yawa')
You can use an IN clause here to avoid the repetition i.e.
AND (c.procdesc IN ('prec', 'pros', 'vat', 'vet', 'pak', 'pren', 'maser', 'lolo', 'yawa'))

Is there a way to combine all the outputs into one in MS-ACCES?

I want to make a SQL Filter in MS-Acces where I have the Option to filter all the Elements in the table. But when I make the UNION SELECT, I can show only 1 column in each row, so I made database_geräte.* to database_geräte.ID .
This works fine now, but I want all the Outputs from the database_geräte.ID select into one row, so that I can Filter all of them at once.
I tried to make a GROUPCONCAT, but that gives me an error.
SELECT database_geräte.ID, dbo.GROUPCONCAT (STRINGVALUE) FROM database_geräte
UNION
SELECT database_geräte.Gerät FROM database_geräte;
I also tried to make a count on the
database_geräte.ID
But then I get the value of the database_geräte.ID select, which doesn't fit in the filter because a ID with that number doesn't exist...
The SQL Select:
SELECT database_geräte.ID, dbo.GROUPCONCAT FROM database_geräte
UNION
SELECT database_geräte.Gerät FROM database_geräte;
The SQL filter in VBA:
sql = "SELECT* FROM database1 WHERE Gerät = '" & Me.GeräteFilter & "'"
Me.sb_1.Form.RecordSource = sql
Me.sb_1.Form.Requery
So the Filter should show an option where I can filter all the elements of the table and show it in the subform.
I just made an UNION that gives me all the data at once.
The SQL Select:
SELECT ID, Gerät FROM database_geräte UNION select "*" as ID, "Alle" as Gerät from database_geräte;
Then I made a function, that I can give to two Filters:
sql = "SELECT database_geräte.Gerät, database1.Name, database1.Grund, database1.Gerät_ID" _
& " FROM database_geräte INNER JOIN database1 ON database_geräte.ID = database1.Gerät_ID " _
& "" & IIf(Me.GeräteFilter <> "*", "Where database1.Gerät_ID = " & Me.GeräteFilter & " ", "") & " " _
& "" & IIf(Me.Person <> "Alle", IIf(Me.GeräteFilter <> "*", " AND database1.Name = '" & Me.Person & "'", "WHERE database1.Name = '" & Me.Person & "'"), "") & ""
Me.sb_1.Form.RecordSource = sql
Me.sb_1.Form.Requery

MS ACCESS SQL Join Subquery

I have two tables: newparts, storedparts
I insert the parts of the newparts, which are not jet in the storedparts into the storedparts:
SQL_String = "INSERT INTO storedparts " & _
"SELECT newparts.* " & _
"FROM storedparts " & _
"RIGHT JOIN newparts ON (storedparts.identifier = newparts.identifier) AND (storedparts.timeStamp = newparts.timeStamp) " & _
"WHERE ((storedparts.AutoID) Is Null);"
This is working fine so far. Now the Problem: Table storedparts is getting so big that the programm is taking too Long for the join process. My solution: Just compare the newparts not to all parts of the storedparts, but just to parts that aren't older than 4 days... I tried a subquery like this, but i can't get it to run.
SQL_String = "INSERT INTO storedparts " & _
"SELECT newparts.* " & _
"FROM storedparts (WHERE storedparts.timestamp > Now() - 4) " & _
"RIGHT JOIN newparts ON (storedparts.identifier = newparts.identifier) AND (storedparts.timeStamp = newparts.timeStamp) " & _
"WHERE ((storedparts.AutoID) Is Null);"
Any help is appreciated.
This wouldn't be a problem if your tables have indexes.
CREATE INDEX ndx_sp_identifier ON storedparts (identifier);
CREATE INDEX ndx_np_identifier ON newparts (identifier);
Then I suggest you change your query to something like this as #jarlh pointed out.
INSERT INTO storedparts
SELECT newparts.*
FROM newparts
LEFT JOIN storedparts
ON newparts.identifier = storedparts.identifier
AND newparts.timeStamp = storedparts.timeStamp
WHERE storedparts.AutoID Is Null;
You could add the where clause after the join statements and see if it improves the performance of the query . Else Try this and see if it works
SQL_String = "INSERT INTO storedparts " & _
"SELECT newparts.* " & _
"FROM ( SELECT * FROM storedparts WHERE
storedparts.timestamp > DateAdd ( 'd', -4, Now()) )sparts" & _
"RIGHT JOIN newparts ON (sparts.identifier = newparts.identifier) AND
(sparts.timeStamp = newparts.timeStamp) " & _
"WHERE ((sparts.AutoID) Is Null);"

How to make stored procedure in if..End if condition

I am beginner at stored procedures. I tried the following stored procedure in IF...End If condition so how to make it ... I am confused.... so anyone create it
strSql = "SELECT count(*) " & _
" FROM hist_billgen_report r, hist_billgen_header h " & _
" WHERE r.invoice_number=h.invoice_number " & _
" and h.macnum = '" & l_macnum & "' " & _
" and r.rep_type = 1 " & _
" and r.rep_call_type = '" & line_type & "' " & _
" and h.billing_job_id = '" & arg_job & "' "
'Special code for data lines for Newcore
If gcompany = "NCW" Then
strSql += " and r.rep_number not in ( "
strSql += "select distinct a.mdn from order_wireless a where"
strSql += " a.id in"
strSql += " ("
strSql += " select c.serviceid from cust_charge_file b, service_charges c, main_company_utilities d"
strSql += " where(b.chg_main_index = c.chargeid)"
strSql += " and c.serviceid = a.id"
strSql += " and (b.chg_main_category_id = d.utilities_id and d.utilities_type = 'CS' and (utilities_desc_short like '%FDS1%' or utilities_desc_short like '%FDS2%' or utilities_desc_short like '%FDS3%' or utilities_desc_short like '%MBS1%' or utilities_desc_short like '%MBS2%' or utilities_desc_short like '%MBS3%' ) )"
strSql += " )"
strSql += " and a.accountnumber = '" & l_macnum & "' "
strSql += " )"
End If
Putting a query into a stored procedure doesn't necessarily always mean a performance increase. Depending on the data in your tables, this query could be quite slow due to the OR LIKES '%%' in it, but you could do something like this:
create procedure [dbo].[spname]
#l_macNum int -- note, you haven't given a lot of information, create all query parameters with appropriate types here
-- more parameters
#arg_job int -- same
AS
BEGIN
if (#company = 'NCW')
begin
SELECT count(*)
FROM hist_billgen_report r, hist_billgen_header h
WHERE r.invoice_number=h.invoice_number
and h.macnum = #l_macNum
-- etc
and r.rep_number not in (
-- etc
)
end
else
begin
SELECT count(*)
FROM hist_billgen_report r, hist_billgen_header h
WHERE r.invoice_number=h.invoice_number
and h.macnum = #l_macNum
-- etc
end
END
GO
note the If and else logic are completely separate queries, as you cannot do what I think you were hoping to do in a contiguous query, without using dynamic sql. there are certain caveats to this but given you're new to sql, going to stick with that
I used -- etc as place holders for your text, as I'm not going to provide the entire solution :P
If that doesn't make sense, let me know.

Syntax error in SQL query

I am having problems implementing this query in vb.net.
The error message that I am getting is with the "as" in the first line.
This is a local sql compact database 3.5
cmd.CommandText = "UPDATE player as a " &
"SET starter = 'TRUE' " &
"WHERE NOT EXISTS (SELECT '1' " &
"FROM player AS b " &
"WHERE(b.school = a.school) " &
"AND b.weight = a.weight " &
"AND b.skill > a.skill)"
cmd.ExecuteNonQuery()
Error message - http://i40.tinypic.com/34gms5z.png
cmd.CommandText = "UPDATE a " &
"SET starter = 'TRUE' " &
"FROM player a " &
"LEFT JOIN player b " &
"ON a.school = b.school " &
"AND a.weight = b.weight " &
"AND b.skill > a.skill " &
"WHERE b.school is NULL"
cmd.ExecuteNonQuery()
Error message - http://i40.tinypic.com/106kn86.png
Does this work?
UPDATE player
SET starter = 'TRUE'
WHERE NOT EXISTS
(
SELECT * FROM player b
WHERE b.school = player.school
AND b.weight = player.weight
AND b.skill > player.skill
)
Edited to add:
This will probably run faster if you create an index:
CREATE INDEX player_school_weight ON player (school, weight, skill)
I believe that you want this:
UPDATE pl
SET
starter = 'True'
FROM
[Player] pl
LEFT JOIN
[Player] pl2 ON (pl.[School] = pl2.[School])
AND
(pl.[Weight] = pl2.[Weight])
AND
(pl2.[Skill] > pl.[Skill])
WHERE pl2.[School] IS NULL