Board logo

標題: SQL 問題...急... [打印本頁]

作者: angusmike    時間: 2008-11-13 20:54     標題: SQL 問題...急...

A  係B既上司
|
B 係C既上司 (LEVEL 1)
|
C (LEVEL 2)

empNo sempNo(佢上司)
A           
B            A
C            B

點先可以COUNT到佢 係LEVEL 1  定 LEVEL 2?
作者: chiefumpire    時間: 2008-11-13 21:10

一定要用 SQL ?
最多只有 LEVEL 2 ?
作者: Kenny仔    時間: 2008-11-13 21:13

count到架咩 你level2同level1都有上司
你要add番個column(level)
作者: thinkpanda    時間: 2008-11-13 21:18

原帖由 angusmike 於 2008-11-13 20:54 發表
A  係B既上司
|
B 係C既上司 (LEVEL 1)
|
C (LEVEL 2)

empNo sempNo(佢上司)
A           
B            A
C            B

點先可以COUNT到佢 係LEVEL 1  定 LEVEL 2?


it is a well known problem in relational database, known as "Parts Explosion Problem", which cannot simply be solved by single SQL statement.

You may want to modify the data structure to make it more SQL SELECT friendly (as a price of INSERT/UPDATE performance)
作者: kamchihau    時間: 2008-11-13 22:36

提示: 作者被禁止或刪除 內容自動屏蔽
作者: 必思    時間: 2008-11-14 10:32

原帖由 kamchihau 於 2008-11-13 22:36 發表
A : fieldserial=01
B : fieldserial=0101
C : fieldserial=010101
select * from table where fieldserial like '01%' and length(fieldserial)='2' ------------->level 1
select * from table where fieldserial  ...

咁設計,第時多個B1 under 阿B, B1做C既阿頭,你個query咪死
作者: thinkpanda    時間: 2008-11-14 10:53

我以前做過類似問題既做法係: (Staff, Ancestor) 結構, 用番樓主既例子

(A, A)
(B, A)
(B, B)
(C, A)
(C, B)
(C, C)

咁要數C係第幾層, 就只要 select count(*) from XXX where staff='C'
呢個方法亦避免左#6 既問題
要加個B1係B同C之間, 只需要insert record, 唔使update
Algorithm 係 :
1. 為新staff 既每個上司同自己加一個record. 即加入
(B1, A)
(B1, B)
(B1, B1)
可以用二句SQL 做到
insert into XXX (staff, ancestor) select 'B1', ancestor from XXX where staff='C'  /* C is the one being replaced */
insert into XXX (staff, ancestor) values ('B1', 'B1')
2. 為每個下屬加一個record, 即加入.
(C, B1)
可以用一句SQL 做到
insert into XXX (staff, ancestor) select staff, 'B1' from XXX where ancestor='C'
要移除一個staff, 只需要以下既SQL
delete from XXX where staff='B1' or ancestor='B1'
唔鍾意"or" 既 分兩句亦得.

要數下有幾多下屬都可以用一句SQL 搞掂
select count(*)-1 from staff where ancestor='B'

呢個結構既好處係可以用固定數目既SQL statement 做任何加減動作, 亦充份利用database index, 唔會涉及table scan 動作, 快速讀取資料....

[ 本帖最後由 thinkpanda 於 2008-11-14 11:11 編輯 ]
作者: laputafish    時間: 2008-11-14 13:42

原帖由 thinkpanda 於 2008-11-14 10:53 發表
我以前做過類似問題既做法係: (Staff, Ancestor) 結構, 用番樓主既例子

(A, A)
(B, A)
(B, B)
(C, A)
(C, B)
(C, C)

咁要數C係第幾層, 就只要 select count(*) from XXX where staff='C'
呢個方法亦避免左#6 既問 ...

但會否失去左d 資料, 好似 上司同佢下屬果個直屬關係.
例如  C 係直屬 B, 唔係直屬 A. 雖然 A 始終係o向 C 之上.

作者: Rudy    時間: 2008-11-14 13:48

原帖由 thinkpanda 於 2008-11-13 21:18 發表


it is a well known problem in relational database, known as "Parts Explosion Problem", which cannot simply be solved by single SQL statement.

You may want to modify the data structure to make it mo ...


我覺得你應該係教書的...... 利害.
作者: thinkpanda    時間: 2008-11-14 14:02

原帖由 laputafish 於 2008-11-14 13:42 發表

但會否失去左d 資料, 好似 上司同佢下屬果個直屬關係.
例如  C 係直屬 B, 唔係直屬 A. 雖然 A 始終係o向 C 之上.


咁得唔得, 好似有D煩,

select ancestor from XXX as x1
where staff='C'
and (select count(*) from XXX as x2 where x2.staff=x1.ancestor) = (select count(*) from XXX as x3 where x3.staff=x1.staff) -1
作者: Rudy    時間: 2008-11-14 16:55

吾知我有無理解錯, 不過我試一下用一個較簡單的方法.
假設樓主的Table Name 係TableA
假如這間公司只有三層架構, 咁樣, 可以用以下這句SQL找到沒有下屬的員工:

Select empno, '(Level 2) 沒有下屬的員工'  from TableA where empno not in (Select sempno from TableA where sempno is not null)
作者: Rudy    時間: 2008-11-14 16:56

換言之, 可以用以下這句SQL 找到中層的員工:
Select sempno, '(Level 1)中層的員工'  from TableA where empno  in (Select empno  from TableA where empno not in (Select sempno from TableA where sempno is not null))
作者: Rudy    時間: 2008-11-14 16:57

亦即係話, 可以用以下這句SQL 找到最上層的員工:
Select sempno, '(Level 0)最高層的員工'  from TableA where empno  in (Select empno from TableA where empno in (Select sempno  from TableA where empno not in (Select sempno from TableA where sempno is not null)))
作者: Rudy    時間: 2008-11-14 17:00

如此類推, 就算樓主的公司有十層架構, 我都可如此類推找到....
咁, 假設有員工'X', 我們可以用以下的SQL, 試出佢係吾係中層員工, 若有Record return, 則是.
Select sempno, '(Level 1)中層的員工'  from TableA where empno  in (Select empno  from TableA where empno not in (Select sempno from TableA where sempno is not null)) and sempno = 'X'
作者: Rudy    時間: 2008-11-14 17:05

若想知X是否沒有下屬那一類(最底層), 可用以下SQL:

Select empno, '(Level 2) 沒有下屬的員工'  from TableA where empno not in (Select sempno from TableA where sempno is not null) and sempno = 'X'

當然, 亦有機會是X既沒下屬也無上司.
不過希望樓主舉一反三, 只不過加個 "And", 就可輕易解決.

[ 本帖最後由 Rudy 於 2008-11-14 17:08 編輯 ]
作者: Rudy    時間: 2008-11-14 17:09

樓主不妨直接Copy & Paste, 試下我的SQL對不對?





歡迎光臨 電腦領域 HKEPC Hardware (https://www.hkepc.com/forum/) Powered by Discuz! 7.2