PDA

View Full Version : تبدیل سطر به شتون



Amirtak
سه شنبه 09 مهر 1387, 13:24 عصر
http://barnamenevis.org/forum/C:%5CDocuments%20and%20Settings%5Cmalaki%5CDesktop %5CUntitled-1.jpgسلام .من یه جدول به شکل زیر دارم.
Time Date per_no
--------- ---------- ----------
31871386120409:2825451386120409:2962031386120409:2 931871386120409:2931871386120409:30
چطوری میطونم اونو بشکل زیر در بیارم
Per_no Date t1 t2 t3 t4 t5 t6
-----------------------------------------------------------------------
3187 13861204 09:28 09:29 09:30 null nulll null
2545 13861204 09:29 null null nulll null null
6203 13861204 09:29 null null nulll null null

در ضمن مقدار ساعت ها ثابت نبوده و هر ساعتی میتواند باشد

لطفاً کمک کنید...

Amirtak
سه شنبه 09 مهر 1387, 13:27 عصر
این هم عکس از جدول اصلی
http://amirtak.parsaspace.com/Untitled-1.jpg
http://barnamenevis.org/forum/C:%5CDocuments%20and%20Settings%5Cmalaki%5CDesktop %C3%99%C2%BEUntitled-1.jpg

Mohammad_Mnt
سه شنبه 09 مهر 1387, 13:31 عصر
من دقیقا" کار نکردم باهاش ولی با گزینه PIVOT توی MSSQL می شه فکر کنم.

پ.ن. : http://www.setfocus.com/technicalarticles/sql-server-2005-tsql.aspx

Amirtak
سه شنبه 09 مهر 1387, 13:38 عصر
مشکل اینجاست مقدار ساعت مشخص و ثابت و معلوم نیست...
لطفا بیشتر راهنمایی کنید

Amirtak
چهارشنبه 10 مهر 1387, 18:22 عصر
واقعا كسي نيست كه كمك كنه؟؟

sheitoonbala
چهارشنبه 10 مهر 1387, 19:17 عصر
سلام. اگه کسی جواب نداده شاید درست متوجه نشدن می خوای چی کار کنی....
- آیا برای هر per_no یک تاریخ هست و n تا زمان ؟
- برای رکورد 6203 دو تا زمان 9:29 و 9:32 وجود داره ولی فقط یکیشو بعد از تبدیل وارد کردی.همچنین سایرper_Noها. چرا؟
- حداکثر تعداد time برای هر Per_No چند تاست؟
- اگه per_no و date ثابت هستند و فقط time تغییر می کنه چه لزومی هست که همش رو توی 1 جدول بذاری؟چرا از کلید خارجی استفاده نمی کنی؟
- .....

Amirtak
پنج شنبه 11 مهر 1387, 12:52 عصر
sheitoonbala ممنون که توجه نشان دادید.
در حقیقت این یکسری اطلاعات است که از دستگاه کارتزنی خوانده میشود.
-برای هر per_no چندین تاریخ و برای هر تاریخ حداکثر 12 زمان وجود دارد وجود دارد.
-حالا می خوام تمام زمانها مربوط به یک per_no در یک تاریخ را توی یک سطر بیاره.
ممنون میشم اگه کمک کنید...

ASKaffash
شنبه 13 مهر 1387, 08:18 صبح
سلام
از این کد استفاده کن شبیه درخواست شماست :


Select T0.Per_No,T0.Io_Date,
A5=T5.Io_Time,
A4=T4.Io_Time,
A3=T3.Io_Time,
A2=T2.Io_Time,
A1=T1.Io_Time
From (Select Per_No,Io_Date From TBL Group By Per_No,Io_Date) T0
Left Join (Select Top 1 Per_No,Io_Date,Io_Time From TBL Order By Io_Time Desc) T1 On(T1.Per_No=T0.Per_No and T1.Io_Date=T0.Io_Date)
Left Join (Select Top 2 Per_No,Io_Date,Io_Time From TBL Order By Io_Time Desc) T2 On(T2.Per_No=T0.Per_No and T2.Io_Date=T0.Io_Date)
Left Join (Select Top 3 Per_No,Io_Date,Io_Time From TBL Order By Io_Time Desc) T3 On(T3.Per_No=T0.Per_No and T3.Io_Date=T0.Io_Date)
Left Join (Select Top 4 Per_No,Io_Date,Io_Time From TBL Order By Io_Time Desc) T4 On(T4.Per_No=T0.Per_No and T4.Io_Date=T0.Io_Date)
Left Join (Select Top 5 Per_No,Io_Date,Io_Time From TBL Order By Io_Time Desc) T5 On(T5.Per_No=T0.Per_No and T5.Io_Date=T0.Io_Date)
Order By T0.Per_No,T0.Io_Date

ولی پیشنهاد میکنم از این روشها استفاده نشود و در لایه برنامه کاربردی و با استفاده از یک گزارش ساز پویا گزارش را ایجاد کنید

Amirtak
شنبه 13 مهر 1387, 08:39 صبح
ASKaffash (http://barnamenevis.org/forum/member.php?u=63973) ممنون. ولی این کد جواب نداد یعنی نتیجه اونی که من میخاستم نیست

Amirtak
شنبه 13 مهر 1387, 10:47 صبح
حالا کسی هست با این شرایط نظری بده؟
اساتید

ASKaffash
یک شنبه 14 مهر 1387, 08:49 صبح
سلام
نمی خواستم این راه را بروم !
اول این تابع را ایجاد کنید :


Create Function GetTime(@Per_No BigInt,@Io_Date Char(8),@n TinyInt)
Returns Char(5)
As
Begin
Declare @i TinyInt,@r Char(5),@RtnValue Char(5)
Declare TmPCursor Cursor For
Select Io_Time From InOut Where Per_No=@Per_No and Io_Date=@Io_Date Order By Io_Time
Open TmPCursor
Select @i=0,@RtnValue=''
While 1=1 Begin
Fetch Next From TmPCursor Into @r
If @@Fetch_Status<>0 Break
If @i=@n-1 Begin
Set @RtnValue=@r
Break
End
Set @i=@i+1
End
Close TmPCursor
Deallocate TmPCursor
Return @RtnValue
End

سپس از این دستور استفاده کنید:


Select Per_No,Io_Date
,A1=dbo.GetTime(Per_No,Io_Date,1)
,A2=dbo.GetTime(Per_No,Io_Date,2)
,A3=dbo.GetTime(Per_No,Io_Date,3)
,A4=dbo.GetTime(Per_No,Io_Date,4)
,A5=dbo.GetTime(Per_No,Io_Date,5)
,A6=dbo.GetTime(Per_No,Io_Date,6)
,A7=dbo.GetTime(Per_No,Io_Date,7)
,A8=dbo.GetTime(Per_No,Io_Date,8)
,A9=dbo.GetTime(Per_No,Io_Date,9)
From (Select Per_No,Io_Date From InOut Group By Per_No,Io_Date) T
Order By Per_No,Io_Date

Amirtak
یک شنبه 14 مهر 1387, 09:11 صبح
ASKaffash (http://barnamenevis.org/forum/member.php?u=63973) جان دمت گرم خیلی باهال بود وخیلی حال کردم.
البته خودم بالاخره موفق شدم با کرسرها بنویسمش. ولی خیلی پیچیده شد. یه دلیلشم واسه این بود کل خواستم واسه کل روزهای ماه اینارو بیاره و اگه شخص اون روز نبود Null بزاره
.
فقط ببخشیدا واسه چی گفته بودی "نمی خواستم این راه را بروم !"

این کد منه که حاصل رو توی یه جدول میریزه :
Create PROCEDURE [dbo].[sp_insert_timeshift]
@Year varchar(4),
@mon varchar(2),
@day_mon varchar(2)
AS
BEGIN
Declare @intday tinyint
Declare @strday Varchar(2)
Declare @rc tinyint
Declare @fl tinyint
Declare @tsdate varchar(6)
set @tsdate='ts'+'1386'
--***************************************
EXEC sp_rename @tsdate,'tbltmp'
--***************************************
Declare Cur0 Cursor for select Distinct per_no from tbltmp
where substring(IO_Date,5,2)='12'
Declare @per_no varchar(4)
Open Cur0
Fetch next From Cur0 into @per_no
while @@fetch_status=0
begin
set @intday=1
while not(@intday>'29')
begin
set @strday=cast(@intday as varchar(2))
if len(@strday)=1
set @strday='0'+@strday
set @rc=(select count(*) from TimeShift
where ((Date='1386'+'12'+@strday) and (Per_No=@per_no)))
if @rc=0
INSERT INTO TimeShift
(Per_No, Date, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)
VALUES (@per_no,'1386'+'12'+@strday,'00:00','00:00','00:0 0','00:00','00:00','00:00','00:00','00:00','00:00' ,'00:00','00:00','00:00')
set @fl=0
Declare Cur2 Cursor for select IO_Time from tbltmp
where ((IO_Date='1386'+'12'+@strday) and (Per_No=@per_no))
Declare @IO_Time varchar(5)
Declare @Tn varchar(3)
Open Cur2
Fetch next from Cur2 into @IO_Time
while @@fetch_status=0
begin
set @fl=@fl+1
-- set @Tn='T'+LTrim(RTrim(cast(@fl as varchar(2))))
if @fl=1
Update TimeShift
set T1=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=2
Update TimeShift
set T2=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=3
Update TimeShift
set T3=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=4
Update TimeShift
set T4=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=5
Update TimeShift
set T5=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=6
Update TimeShift
set T6=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=7
Update TimeShift
set T7=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=8
Update TimeShift
set T8=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=9
Update TimeShift
set T9=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=10
Update TimeShift
set T10=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=11
Update TimeShift
set T11=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
Else if @fl=12
Update TimeShift
set T12=@IO_Time where ((per_no=@per_no) and (Date='1386'+'12'+@strday))
fetch next from Cur2 into @IO_Time
End
close Cur2
Deallocate Cur2
set @intday=@intday+1
End
Fetch next From Cur0 into @per_no
End
close Cur0
Deallocate Cur0
--***************************************
EXEC sp_rename 'tbltmp',@tsdate
END

ASKaffash (http://barnamenevis.org/forum/member.php?u=63973) میشه راجع به کد من نظر بدی استاد؟

ASKaffash
سه شنبه 16 مهر 1387, 11:48 صبح
سلام
اگر پروژه شما یک سیستم جدی است این موارد را مد نظر قراردهید :
- "نمی خواستم این راه را بروم" ترجیحا فرار از کرسر چون کندتراست
- تعداد کرسرهای بکار رفته شما زیاد است در حجم زیاد کندی ایجاد میکند(به خصوص تودرتوست)
- استفاده از Insert درون یک جدول دیگر سپس استخراج نتایج نیز در شرایط افزایش رکوردها وحشنتاک کندی ایجاد میکند
-با این تعداد if و استفاده از مثلا IO_Date='1386'+'12'+@strday برنامه شما از حالت پویائی خارج شده است
ولی اگر پروژه شما کوچک است اصلا مهم نیست من برای داده های حجیم راه حل خودم را نیز نادرست میدانم و تکرار میکنم میشود در لایه برنامه کاربردی واز ابزارهای Dynamic نیز این کار را انجام داد