Need help to figure out syntax error code - syntax-error

I've been following a few snippits given by professor to fill in gaps of code and now that I am finished I'm get and I keep getting error and can't figure out what its asking
Error (10500): VHDL syntax error at engine.vhd(30) near text "when"; expecting ";"
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity engine is
port(
RST, CLK, KEY0: in std_logic;
Y3, Y2, Y1, Y0: out std_logic
);
end entity;
architecture behav of engine is
type states is (RESET, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20);
signal D: states;
signal Q: states;
begin
REG: process(all)
begin
if RST = '0' then Q <= RESET;
elsif rising_edge(CLK) then Q <= D;
end if;
end process;
NSL: process(all)
begin
D <=
T1 when Q = T0 else -- line 30
T2 when Q = T1 else
T3 when Q = T2 else
T4 when Q = T3 else
T5 when Q = T4 else
T6 when Q = T5 else
T7 when Q = T6 else
T8 when Q = T7 else
T9 when Q = T8 else
T10 when Q = T9 else
T11 when Q = T10 else
T12 when Q = T11 else
T13 when Q = T12 else
T14 when Q = T13 else
T15 when Q = T14 else
T16 when Q = T15 else
T17 when Q = T16 else
T18 when Q = T17 else
T19 when Q = T18 else
T20 when Q = T19 else
T0;
end process;
with Q select
Y <= B"1000" when T1 | T2 | T3 | T4 | T5,
B"0100" when T6 | T7 | T8 | T9 | T10,
B"0010" when T11 | T12 | T13 | T14 | T15,
B"0001" when T16 | T17 | T18 | T19 | T20,
B"0000" when others;
end architecture;

when is only supported inside a process when the VHDL standard is set to 2008 or later.
In your code example, there is no need for a process and the assignment to D can be done without the process.

Related

How to join on a default value from the 2nd table if no match is found?

I'm looking for a way to join 2 tables as follows:
T1: T2:
a b c d e
------- -------------
1 b1 1 d1 e1
2 b2 2 d2 e2
3 b3 ST d0 e0
--> join on T1.a = T2.c (if no match found join on T1.c = ST)
a b c d e
----------------------
1 b1 1 d1 e1
2 b2 2 b2 e2
3 b3 ST d0 e0 <- No match found so ST values are used.
Right now I only found a way when T2.c are integers. I do a conditional join en afterwards i take the max value of c en group by every other column.
Is there any way to do this with string values like in the example in the match column?
Thanks
You want a default. You can use left join:
select t1.*, coalesce(t2.c, t2def.c) as c,
coalesce(t2.d, t2def.d) as d, coalesce(t2.e, t2def.e) as e
from t1 left join
t2
on t1.a = t2.c left join
t2 t2def
on t2def.c = 'ST';
Or, you can use apply:
select t1.*, t2.*
from t1 outer apply
(select top (1) t2.*
from t2
where t2.c in ('ST', t1.a)
order by (case when t2.c = 'ST' then 2 else 1 end)
) t2;

SQL add values of rows, if columns are switched

After a join of the same table, I have a result like this:
c1 c2 count
A B 5
A C 4
B A 2
B C 2
C A 1
Now, the numbers should been added, if c1 and c2 are switched, like this:
c1 c2 count
A B 7
A C 5
B C 2
How can this be done with a query?
Using a left join to self join the table on inverse positions and returning those where c1 is less than c2, or it had no matching row. Using coalesce to add 0 when the left joined count is null.
select
t.c1
, t.c2
, t.count + coalesce(s.count,0) as count
from t
left join t as s
on t.c1 = s.c2
and t.c2 = s.c1
where t.c1 < t.c2 or s.c1 is null
rextester demo in sql server: http://rextester.com/VBQI62112
returns:
+----+----+-------+
| c1 | c2 | count |
+----+----+-------+
| A | B | 7 |
| A | C | 5 |
| B | C | 2 |
+----+----+-------+
Many databases support least() and greatest(). If they are available, you can do:
select least(c1, c2) as c1, greatest(c1, c2) as c2, sum(count) as cnt
from (<your query here>) t
group by least(c1, c2), greatest(c1, c2);
In databases that don't support these functions, you can use case.
Note: The semantics of least() and greatest() return NULL if either column is NULL, so you may need to be careful if either value could be NULL.
Perhaps join the output c1,c2 with the same c2,c1?
select t1.c1
,t1.c2
,sum(coalesce(t1.count,0), coalesce(t2.count,0))
from table t1
left join table t2
on t1.c1 = t2.c2
and t1.c2 = t2.c1
group by t1.c1, t1.c2
having t1.c1 < t1.c2
SELECT t.c1
, t.c2
, t.cnt + CASE WHEN s.cnt IS NULL THEN 0 ELSE s.cnt END as cnt
FROM t
LEFT JOIN
t as s
ON t.c1 = s.c2
AND t.c2 = s.c1
WHERE t.c1 < t.c2;

Self joining table with a condition

I have a table of the following type:
Table dummy1:
e_n t_s item
a t1 c
a t2 c
a t3 c
a t4 c
b p1 c
b p2 c
b p3 c
b p4 c
t1, t2, t3, t4, p1, p2, p3, p4 are timestamps in ascending order.
t1, t2, t3, t4 are timestamps in ascending order for event_name 'a'.
p1, p2, p3, p4 are timestamps in ascending order for event_name 'b'.
c is the item_number for which these events 'a' and 'b' are occurring.
I am trying to write a query for which the result should be as follows:
e_n1 e_n2 item t_s_1 t_s_2
a b c t1 p1
a b c t2 p2
a b c t3 p3
a b c t4 p4
I have tried the following code:
select l.e_n as e_n_1, m.e_n as e_n_2, l.item, l.t_s as t_s_a,
m.t_s as t_s_b from (
(select * from dummy where e_n = 'a') l
join
(select * from dummy where e_n = 'b') m
on l.item = m.item and l.t_s < m.t_s
The join l.item = m.item is needed as there are many other items c1, c2, c3 with the same structure
The result is:
e_n1 e_n2 item t_s_a t_s_b
a b c t1 p1
a b c t1 p2
a b c t1 p3
a b c t1 p4
a b c t2 p1
a b c t2 p2
a b c t2 p3
so on
How can I achieve my result in an efficient way?
select min (case when e_n = 'a' then 'a' end) as e_n1
,min (case when e_n = 'b' then 'b' end) as e_n2
,item
,min (case when e_n = 'a' then t_s end) as t_s_1
,min (case when e_n = 'b' then t_s end) as t_s_2
from (select d.*
,row_number () over (partition by item,e_n order by t_s) as rn
from dummy as d
) d
group by item
,rn
+------+------+------+-------+-------+
| e_n1 | e_n2 | item | t_s_1 | t_s_2 |
+------+------+------+-------+-------+
| a | b | c | t1 | p1 |
| a | b | c | t2 | p2 |
| a | b | c | t3 | p3 |
| a | b | c | t4 | p4 |
+------+------+------+-------+-------+
First, Sort by timestamp for every event then join on sorted table row number.
try below code.
select l.e_n as e_n_1, m.e_n as e_n_2, isnull(l.item,m.item) as item, l.t_s as t_s_a,
m.t_s as t_s_b from
(select *,(row_number() over (order by t_s)) as rn from dummy where e_n = 'a') l
full join
(select *,(row_number() over (order by t_s)) as rn from dummy where e_n = 'b') m
on l.item = m.item and l.rn=m.rn

Removing string from sql

Please see below data..
Table A
AID NAME
1 A
2 B
3 C
4 D
5 E
6 F
Table B
BID AID NAME
1 1 T1
2 1 T2
3 2 T3
4 2 T4
5 3 T5
6 4 T6
7 1 T7
8 1 T8
9 2 T9
10 2 T10
11 3 T11
12 4 T12
I am using this statement
SELECT
dbo.A.NAME AS ANAME, dbo.B.NAME AS BNAME
FROM
dbo.A
LEFT OUTER JOIN
dbo.B ON dbo.A.AID = dbo.B.AID
Its returning these results:
ANAME BNAME
A T1
A T2
A T7
A T8
B T3
B T4
B T9
B T10
C T5
C T11
D T6
D T12
E NULL
F NULL
but I need following result
ANAME BNAME
A T1
T2
T7
T8
B T3
T4
T9
T10
C T5
T11
D T6
T12
E NULL
F NULL
How to remove extra names from above?
Try this
SELECT CASE WHEN ROW_NUMBER() OVER ( PARTITION BY A.NAME ORDER BY A.NAME ) = 1
THEN A.NAME
ELSE ''
END AS ANAME ,
dbo.B.NAME AS BNAME
FROM dbo.A
LEFT OUTER JOIN dbo.B ON dbo.A.AID = dbo.B.AID;
I guess something like the following could be done if absolutely needed to do in SQL, seeing as it is presentation.
SELECT CASE WHEN ROW_NUMBER() OVER ( PARTITION BY A.AID ORDER BY A.AID ) > 1
THEN ''
ELSE A.NAME
END AS ANAME ,
dbo.B.NAME AS BNAME
FROM dbo.A
LEFT OUTER JOIN dbo.B ON dbo.A.AID = dbo.B.AID;
You can use below SQL query to get your desired output:
SELECT (CASE WHEN SrNo = 1
THEN ANAME
ELSE ''
END) AS ANAME
, BNAME
FROM (
SELECT ROW_NUMBER OVER (PARTITION BY dbo.A.NAME ORDER BY dbo.B.NAME) AS SrNo,
dbo.A.NAME AS ANAME, dbo.B.NAME AS BNAME
FROM dbo.A LEFT OUTER JOIN
dbo.B ON dbo.A.AID = dbo.B.AID
) AS tbl

Join itself quest

I have table like this:
ID DADOS TIPO
1 UM 1
2 DOIS 1
3 TRES 1
4 QUATRO 1
5 CINCO 1
1 SEIS 2
I need to make a select that return this:
t1.id t1.dados t2.dados
1 Um Seis
2 Dois Null
3 Tres Null
4 Quatro Null
5 Cinco Null
I tried in this form:
SELECT T1.ID, T1.DADOS, T2.DADOS
FROM Tabela1 as T1 LEFT JOIN Tabela1 AS T2 ON T1.ID = T2.ID
WHERE T1.TIPO = 1 AND T2.TIPO = 2
But the result is this:
ID T1.DADOS T2.DADOS
1 UM SEIS
What I am doing wrong?
use this code for join table itself :
SELECT T1.ID, T1.DADOS, T2.DADOS
FROM Tabela1 as T1 LEFT JOIN Tabela1 AS T2 ON T1.ID = T2.ID
And T1.TIPO = 1 AND T2.TIPO = 2
also you can use this code :
SELECT T1.ID, T1.DADOS, T2.DADOS
FROM
( select * from Tabela1 T_1
where T_1.TIPO = 1) as T1
LEFT JOIN
(select * from Tabela1 T_2
Where T_2.TIPO = 2) AS T2 ON T1.ID = T2.ID
By using the clause WHERE T1.TIPO = 1 AND T2.TIPO = 2, you require that a matching record are found in T2, and thus in reality you are turning the left join into an inner join.
In order to include the records from T1 that have no matching record in T2, you can change the where clause to either
WHERE T1.TIPO = 1 AND (T2.TIPO IS NULL OR T2.TIPO = 2)
or
WHERE T1.TIPO = 1 AND T2.TIPO <> 1
This will do the work
SELECT T1.ID, T1.DADOS as T1Dados, T2.DADOS as T2Dados
FROM Tabela1 T1
left JOIN Tabela1 T2
ON T1.ID = T2.ID
and T1.TIPO = 1 and T2.TIPO = 2
See a demo here http://sqlfiddle.com/#!2/c7066/6