473,396 Members | 1,590 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Ask for help from ORACLE board: matching normalized and denormalized tables

I found this problem on ORACLE board.
2 input TABLES:

Items
Id ItemName
1 Phone
2 Table
3 Lamp
4 TV
5 Stereo

ItemsByRooms
Id Room RoomItems
1 Bedroom Phone, Lamp, Bed, TV
2 Kitchen Phone, Table
3 LvRoom Phone, Lamp, TV, Stereo

Expected result:
Results would be:

Id ItemName QtyUsed
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

This Problem wasn't resolved by ORACLE board members.

Here is my solution:
WITH T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')),
T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'))
SELECT CHAR(T2.ID)|| ' '||ITEMNAME "ID ITEM_NAME" ,count(*) AS
QTY_USED
FROM T1,T2
WHERE (LENGTH(STRIP(RoomItems)) - LENGTH(REPLACE(STRIP(RoomItems),
ITEMNAME,''))) 0
GROUP BY CHAR(T2.ID)|| ' '||ITEMNAME;

ID ITEM_NAME QTY_USED
------------------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

5 record(s) selected.

Is there is another solutions?
For example using Recursion.
Thank's in advance Leny G.

--
Message posted via DBMonster.com
http://www.dbmonster.com/Uwe/Forums....m-db2/200806/1

Jun 27 '08 #1
13 1566
lenygold via DBMonster.com wrote:

[snip]
Is there is another solutions?
For example using Recursion.
Naturally... (not that I approve of such horrid structures ;-)

WITH
T1 (ID, ROOM, ITEMS) AS (
VALUES
(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
),
T2 (ID, ITEM) AS (
VALUES
(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo')
),
T3 (ITEMS, I, J, ITEM) AS (
SELECT
ITEMS,
1,
CASE
WHEN LOCATE(',', ITEMS) = 0 THEN LENGTH(ITEMS) + 1
ELSE LOCATE(',', ITEMS) + 1
END,
TRIM(CASE
WHEN LOCATE(',', ITEMS) = 0 THEN ITEMS
ELSE SUBSTR(ITEMS, 1, LOCATE(',', ITEMS) - 1)
END)
FROM T1

UNION ALL

SELECT
ITEMS,
I + 1,
CASE
WHEN LOCATE(',', ITEMS, J) = 0 THEN LENGTH(ITEMS) + 1
ELSE LOCATE(',', ITEMS, J) + 1
END,
TRIM(CASE
WHEN LOCATE(',', ITEMS, J) = 0 THEN SUBSTR(ITEMS, J)
ELSE SUBSTR(ITEMS, J, LOCATE(',', ITEMS, J) - J)
END)
FROM T3
WHERE I < 20
AND J <= LENGTH(ITEMS)
)
SELECT
T2.ID,
T2.ITEM,
COUNT(*) AS COUNT
FROM
T2 INNER JOIN T3 ON T2.ITEM = T3.ITEM
GROUP BY
T2.ID,
T2.ITEM;
Note that the I column in the recursive T3 CTE is only included to
prevent infinite recursion warnings. The J column is the "interesting"
one which calculates the start of the next substring.

The result of the above query is as follows:

ID ITEM COUNT
----------- ------ -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

5 record(s) selected.
Just to prove the recursion is splitting out the ITEMS column
correctly, and to observe the J column incrementing, replace the main
query with "SELECT ITEMS, J, ITEM FROM T3", and the result becomes:

ITEMS J ITEM
----------------------- ----------- -----------------------
Phone, Lamp, Bed, TV 7 Phone
Phone, Table 7 Phone
Phone, Lamp, TV, Stereo 7 Phone
Phone, Lamp, Bed, TV 13 Lamp
Phone, Table 13 Table
Phone, Lamp, TV, Stereo 13 Lamp
Phone, Lamp, Bed, TV 18 Bed
Phone, Lamp, TV, Stereo 17 TV
Phone, Lamp, Bed, TV 21 TV
Phone, Lamp, TV, Stereo 24 Stereo

10 record(s) selected.
It's a bit clearer if "WHERE ID = 1" is added to the initial part of
the T3 query, in which case you get:

ITEMS J ITEM
----------------------- ----------- -----------------------
Phone, Lamp, Bed, TV 7 Phone
Phone, Lamp, Bed, TV 13 Lamp
Phone, Lamp, Bed, TV 18 Bed
Phone, Lamp, Bed, TV 21 TV

4 record(s) selected.
Cheers,

Dave.
Jun 27 '08 #2
Thank you Dave.
We have the best board in world
Cheers. Leny G.

Dave Hughes wrote:
>[snip]
>Is there is another solutions?
For example using Recursion.

Naturally... (not that I approve of such horrid structures ;-)

WITH
T1 (ID, ROOM, ITEMS) AS (
VALUES
(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
),
T2 (ID, ITEM) AS (
VALUES
(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo')
),
T3 (ITEMS, I, J, ITEM) AS (
SELECT
ITEMS,
1,
CASE
WHEN LOCATE(',', ITEMS) = 0 THEN LENGTH(ITEMS) + 1
ELSE LOCATE(',', ITEMS) + 1
END,
TRIM(CASE
WHEN LOCATE(',', ITEMS) = 0 THEN ITEMS
ELSE SUBSTR(ITEMS, 1, LOCATE(',', ITEMS) - 1)
END)
FROM T1

UNION ALL

SELECT
ITEMS,
I + 1,
CASE
WHEN LOCATE(',', ITEMS, J) = 0 THEN LENGTH(ITEMS) + 1
ELSE LOCATE(',', ITEMS, J) + 1
END,
TRIM(CASE
WHEN LOCATE(',', ITEMS, J) = 0 THEN SUBSTR(ITEMS, J)
ELSE SUBSTR(ITEMS, J, LOCATE(',', ITEMS, J) - J)
END)
FROM T3
WHERE I < 20
AND J <= LENGTH(ITEMS)
)
SELECT
T2.ID,
T2.ITEM,
COUNT(*) AS COUNT
FROM
T2 INNER JOIN T3 ON T2.ITEM = T3.ITEM
GROUP BY
T2.ID,
T2.ITEM;

Note that the I column in the recursive T3 CTE is only included to
prevent infinite recursion warnings. The J column is the "interesting"
one which calculates the start of the next substring.

The result of the above query is as follows:

ID ITEM COUNT
----------- ------ -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

5 record(s) selected.

Just to prove the recursion is splitting out the ITEMS column
correctly, and to observe the J column incrementing, replace the main
query with "SELECT ITEMS, J, ITEM FROM T3", and the result becomes:

ITEMS J ITEM
----------------------- ----------- -----------------------
Phone, Lamp, Bed, TV 7 Phone
Phone, Table 7 Phone
Phone, Lamp, TV, Stereo 7 Phone
Phone, Lamp, Bed, TV 13 Lamp
Phone, Table 13 Table
Phone, Lamp, TV, Stereo 13 Lamp
Phone, Lamp, Bed, TV 18 Bed
Phone, Lamp, TV, Stereo 17 TV
Phone, Lamp, Bed, TV 21 TV
Phone, Lamp, TV, Stereo 24 Stereo

10 record(s) selected.

It's a bit clearer if "WHERE ID = 1" is added to the initial part of
the T3 query, in which case you get:

ITEMS J ITEM
----------------------- ----------- -----------------------
Phone, Lamp, Bed, TV 7 Phone
Phone, Lamp, Bed, TV 13 Lamp
Phone, Lamp, Bed, TV 18 Bed
Phone, Lamp, Bed, TV 21 TV

4 record(s) selected.

Cheers,

Dave.
--
Message posted via DBMonster.com
http://www.dbmonster.com/Uwe/Forums....m-db2/200806/1

Jun 27 '08 #3
One question Dave.
What fumction TRIM is doing. I know LTRIM,RTRIM.
Thank's Leny G.

lenygold wrote:
>Thank you Dave.
We have the best board in world
Cheers. Leny G.
>>[snip]
>>Is there is another solutions?
[quoted text clipped - 108 lines]
>>
Dave.
--
Message posted via DBMonster.com
http://www.dbmonster.com/Uwe/Forums....m-db2/200806/1

Jun 27 '08 #4
Another solution:
------------------------------ Commands Entered
------------------------------
WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName, RoomItems) 0
GROUP BY
t2.id
, ItemName;
------------------------------------------------------------------------------

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

5 record(s) selected.

Jun 27 '08 #5
Another solution:
------------------------- Commands Entered -------------------------
WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'),
(6, 'Sofa')
)
SELECT
t2.id
, ItemName
, COUNT(t1.id) AS QtyUsed
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName, RoomItems) 0
GROUP BY
t2.id
, ItemName
;
--------------------------------------------------------------------

ID ITEMNAME QTYUSED
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1
6 Sofa 0

6 record(s) selected.
Jun 27 '08 #6
lenygold via DBMonster.com wrote:
One question Dave.
What fumction TRIM is doing. I know LTRIM,RTRIM.
That's mostly me being lazy :) The query was based on one I wrote a
while back for dealing with comma-separated values in a loading script.
However, those values had no space after the comma, e.g. "A,B,C". Hence
when I did the same thing here I wound up with a leading space. Rather
than fix it "properly" I just threw in a TRIM call - TRIM(value) is
equivalent to LTRIM(RTRIM(value)) (although it's got arguments for
leading / trailing / both as well).

Cheers,

Dave.
Jun 27 '08 #7
Tonkuma wrote:
Another solution:
------------------------------ Commands Entered
------------------------------
WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Bed, TV'),
(2, 'Kitchen', 'Phone, Table'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName, RoomItems) 0
GROUP BY
t2.id
, ItemName;
----------------------------------------------------------------------
--------

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1

5 record(s) selected.
That's a cunning solution! Although I would caution that it shouldn't
be used in practice without a certain amount of care - e.g. if one item
is a prefix of another item, interesting things will happen:

WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Sofabed, TV'),
(2, 'Kitchen', 'Phone, Table, Sofa'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'),
(6, 'Sofa'),
(7, 'Sofabed')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName, RoomItems) 0
GROUP BY
t2.id
, ItemName;

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1
6 Sofa 2
7 Sofabed 1

7 record(s) selected.
Cheers,

Dave.
Jun 27 '08 #8
Leny,

although a solution is posted, I would strongly recommend to re-
consider the table design here as you already violate first normal
form and this will draw up further problems, even when you have solved
this one. For example as you can see in your example, you have "Bed"
in "ItemsByRooms" but no item for it in the items table. This would
not have happened if you had the proper tables and foreign keys in
place.

I would expect the following tables:

CREATE TABLE Rooms
(RoomID INTEGER NOT NULL PRIMARY KEY,
RoomName VARCHAR(30) NOT NULL);

-- This table takes your phone, table, lamp etc each one in a separate
row.
CREATE TABLE Furnishings
(FurnishingID INTEGER NOT NULL PRIMARY KEY,
FurnishingName VARCHAR(30) NOT NULL);

-- This table links rooms to furnishings
CREATE TABLE FurnishedRooms
(RoomID INTEGER NOT NULL
REFERENCES Rooms(RoomID)
ON UPDATE CASCADE,
FurnishingID INTEGER NOT NULL
REFERENCES Furnishings(FurnishingID)
ON UPDATE CASCADE,
PRIMARY KEY (RoomID, FurnishingID));

Then it is easy to get a COUNT on the FurnishingID:

SELECT FR1.FurnishingID,
F1.FurnishingName,
COUNT(FR1.FurnishingID) AS FurnishingTally
FROM Furnishings AS F1
INNER JOIN FurnishedRooms AS FR1
ON F1.FurnishingID = FR1.FurnishingID
GROUP BY FR1.FurnishingID, F1.FurnishingName

Brgds

Philipp Post
Jun 27 '08 #9
On Jun 10, 6:00*pm, "Dave Hughes" <d...@waveform.plus.comwrote:
>
That's a cunning solution! Although I would caution that it shouldn't
be used in practice without a certain amount of care - e.g. if one item
is a prefix of another item, interesting things will happen:
It's easy to avoid the issue by concatenating both argument of LOCATE
function with comma(',').

WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Sofabed, TV'),
(2, 'Kitchen', 'Phone, Table, Sofa'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'),
(6, 'Sofa'),
(7, 'Sofabed')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName||',', RoomItems||',') 0
GROUP BY
t2.id
, ItemName;
--------------------------------------------------------------------

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1
6 Sofa 1
7 Sofabed 1

7 record(s) selected.
Jun 27 '08 #10
I used COUNT(t1.id) instead of COUNT(*) and LEFT JOIN instead of INNER
JOIN.
Because I considered the possibility that some item of T2 would not be
in none of RoomItems of T1.
Jun 27 '08 #11
Tonkuma wrote:
On Jun 10, 6:00*pm, "Dave Hughes" <d...@waveform.plus.comwrote:

That's a cunning solution! Although I would caution that it
shouldn't be used in practice without a certain amount of care -
e.g. if one item is a prefix of another item, interesting things
will happen:

It's easy to avoid the issue by concatenating both argument of LOCATE
function with comma(',').
Nice fix! Barring delimiters appearing within values (which would break
the recursive solution anyway), I can't think of a way to break it.

In fact, I suspect in the case of a purely delimited multi-valued
string (again, assuming the delimiter cannot appear within individual
items) there's never a requirement for recursion (i.e. this use of
LOCATE ought to solve all possible situations).

Recursion's better suited to dealing with a multi-valued string where
each item is prefixed with its length, as in the message column for
exception tables. The InfoCenter's got a nice example of such usage:

http://publib.boulder.ibm.com/infoce.../com.ibm.db2.l
uw.sql.ref.doc/doc/r0001111.html

Or alternatively, when dealing with a more complex structure like
"real" CSV in which quoted values could contain the delimiter (a UDF
for locating the next "real" delimiter could be used with recursion in
such a case to split the string).
WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp, Sofabed, TV'),
(2, 'Kitchen', 'Phone, Table, Sofa'),
(3, 'LvRoom', 'Phone, Lamp, TV, Stereo')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'),
(6, 'Sofa'),
(7, 'Sofabed')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE(ItemName||',', RoomItems||',') 0
GROUP BY
t2.id
, ItemName;
--------------------------------------------------------------------

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1
6 Sofa 1
7 Sofabed 1

7 record(s) selected.

Cheers,

Dave.
Jun 27 '08 #12
I'm sorry that I removed my post before I saw your post.
Here's an updated example(with modified and additional data) which I
added REPLACE functions to remove blanks in ItemName and RoomItems.
WITH
T1 (Id,Room,RoomItems) AS
(VALUES(1, 'Bedroom', 'Phone, Lamp , Sofa bed , TV'),
(2, 'Kitchen', 'Phone , Table , Sofa '),
(3, 'LvRoom', 'Phone,Lamp,TV,Stereo,Sofabed')
)
,T2(Id, ItemName) AS
(VALUES(1, 'Phone'),
(2, 'Table'),
(3, 'Lamp'),
(4, 'TV'),
(5, 'Stereo'),
(6, 'Sofa'),
(7, 'Sofa bed'),
(8, 'PC')
)
SELECT t2.id
, ItemName
, COUNT(t1.id) AS count
FROM T2
LEFT JOIN
T1
ON LOCATE( REPLACE( ItemName, ' ', '') || ','
, REPLACE(RoomItems, ' ', '') || ','
) 0
GROUP BY
t2.id
, ItemName
;
--------------------------------------------------------------------

ID ITEMNAME COUNT
----------- -------- -----------
1 Phone 3
2 Table 1
3 Lamp 2
4 TV 2
5 Stereo 1
6 Sofa 1
7 Sofa bed 2
8 PC 0

8 record(s) selected.
Jun 27 '08 #13
Dave Hughes wrote:
In fact, I suspect in the case of a purely delimited multi-valued
string (again, assuming the delimiter cannot appear within individual
items) there's never a requirement for recursion (i.e. this use of
LOCATE ought to solve all possible situations).
I should amend the above to say "in the case of a purely delimited
multi-valued string where all possible items are known in advance". The
recursive solution would be useful in the case where the items are not
known.
Cheers,

Dave.
Jun 27 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Muzamil | last post by:
hello I've a denormalized table PRODUCTS with following fields: ProductNo , OrderNo , SerialNo , OrderDate , PromiseDate ,
5
by: MJunium | last post by:
I hope someone can help me with this one. For performance reasons, I have a denormalized database. There are two tables in the database we can call them table a and table b. Both of theses...
3
by: Thelma Lubkin | last post by:
I've inherited a SQL statement that looks approximately like this: SELECT Sum(tblA.A9A) As , Sum(tblA.A9A)/Sum(tblA.I9N) As , Sum(tblA.A0A) As , Sum(tblA.A0A)/Sum(tblA.I9N) As FROM INNER...
2
by: Janelle.Dunlap | last post by:
I have a table in my database that is linked to an excel spreadsheet. I need to be able to manipulate the data in this linked table so that I can create smaller normalized tables that work with...
3
by: fkulaga | last post by:
Hi all, I have a problem with the issue in the subject, i have all data in one big excel file, in a denormalized form, and on the other side, i have mysql database with many tables, which is...
1
by: phlype.johnson | last post by:
Suppose we have to design a database for a recruitment agency. There will be a table "candidates" with fields "candidateid","last name","first name" ; the languages mastered by a candidate as well...
1
by: Neekos | last post by:
Hey guys, So after some of you (FishVal, Nico, NeoPa) pointed out previously that my tables are not normalized, i've decided to go back to the drawing board, but im not really sure where to start....
3
by: vikas000000a | last post by:
Hi All, I am new to this forum as far as posting a question is concerned, although I have quite frequently visiting this site as a guest. My quertion relates to preforming fast searched in a very...
5
by: jrod11 | last post by:
hi, I found a jquery html table sorting code i have implemented. I am trying to figure out how to edit how many colums there are, but every time i remove code that I think controls how many colums...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.